Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add sensors in TranslationalPosition #303

Merged
merged 6 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions src/Mechanical/Translational/sensors.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
ForceSensor(; name)

Linear 1D force input sensor.
Linear 1D force sensor, measures the force between two flanges.

# Connectors:

Expand All @@ -10,19 +10,22 @@ Linear 1D force input sensor.
"""
@mtkmodel ForceSensor begin
@components begin
flange = MechanicalPort()
flange_a = MechanicalPort()
flange_b = MechanicalPort()
output = RealOutput()
end

@equations begin
flange.f ~ -output.u
flange_a.v ~ flange_b.v
flange_a.f + flange_b.f ~ 0.0
output.u ~ flange_a.f
end
end

"""
PositionSensor(; s = 0, name)

Linear 1D position input sensor.
Linear 1D position sensor.

# States:

Expand Down Expand Up @@ -53,7 +56,7 @@ end
"""
AccelerationSensor(; name)

Linear 1D position input sensor.
Linear 1D acceleration sensor.

# States:

Expand Down
3 changes: 3 additions & 0 deletions src/Mechanical/TranslationalPosition/TranslationalPosition.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,7 @@ include("components.jl")
export Force
include("sources.jl")

export PositionSensor, ForceSensor, AccelerationSensor
include("sensors.jl")

end
81 changes: 81 additions & 0 deletions src/Mechanical/TranslationalPosition/sensors.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"""
ForceSensor(; name)

Linear 1D force sensor, measures the force between two flanges.

# Connectors:

- `flange_a`: 1-dim. translational flange
- `flange_b`: 1-dim. translational flange
- `output`: real output
"""
@mtkmodel ForceSensor begin
@components begin
flange_a = Flange()
flange_b = Flange()
output = RealOutput()
end

@equations begin
flange_a.s ~ flange_b.s
flange_a.f + flange_b.f ~ 0.0
output.u ~ flange_a.f
end
end

"""
PositionSensor(; s = 0, name)

Linear 1D position sensor.

# States:

- `s`: [m] absolute position (with initial value of 0.0)

# Connectors:

- `flange`: 1-dim. translational flange
- `output`: real output
"""
@mtkmodel PositionSensor begin
@components begin
flange = Flange()
output = RealOutput()
end

@equations begin
output.u ~ flange.s
flange.f ~ 0.0
end
end

"""
AccelerationSensor(; name)

Linear 1D acceleration sensor.

# States:

- `a`: [m/s^2] measured acceleration

# Connectors:

- `flange`: 1-dim. translational flange
- `output`: real output
"""
@mtkmodel AccelerationSensor begin
@components begin
flange = Flange()
output = RealOutput()
end

@variables begin
a(t) = 0.0
end

@equations begin
a ~ D(D(flange.s))
output.u ~ a
flange.f ~ 0.0
end
end
163 changes: 112 additions & 51 deletions test/Mechanical/translational.jl
Original file line number Diff line number Diff line change
Expand Up @@ -115,61 +115,122 @@ end
end

@testset "sources & sensors" begin
function System(; name)
systems = @named begin
pos = TV.Position()
pos_sensor = TV.PositionSensor(; s = 1)
force = TV.Force()
force_sensor = TV.ForceSensor()

spring = TV.Spring(; k = 1000)

src1 = Sine(frequency = 100, amplitude = 2)
src2 = Sine(frequency = 100, amplitude = -1)

pos_value = RealInput()
force_output = RealOutput()
@testset "Translational" begin
@testset "PositionSensor & ForceSensor" begin
function System(; name)
systems = @named begin
pos = TV.Position()
pos_sensor = TV.PositionSensor(; s = 1)
force = TV.Force()
force_sensor = TV.ForceSensor()

spring = TV.Spring(; k = 1000)

src1 = Sine(frequency = 100, amplitude = 2)
src2 = Sine(frequency = 100, amplitude = -1)

pos_value = RealInput()
force_output = RealOutput()
end

eqs = [connect(pos.s, src1.output)
connect(force.f, src2.output)
connect(pos.flange, force_sensor.flange_a)
connect(force_sensor.flange_b, spring.flange_a)
connect(spring.flange_b, force.flange, pos_sensor.flange)
connect(pos_value, pos_sensor.output)
connect(force_output, force_sensor.output)]

ODESystem(eqs, t, [], []; name, systems)
end

@named system = System()
s = complete(system)
sys = structural_simplify(system)
prob = ODEProblem(sys, [], (0, 1 / 400))
sol = solve(prob, Rosenbrock23())

delta_s = 1 / 1000
s_b = 2 - delta_s + 1

@test sol[s.pos_value.u][end]≈s_b atol=1e-3
@test all(sol[s.spring.flange_a.f] .== sol[s.force_output.u])
end

eqs = [connect(pos.s, src1.output)
connect(force.f, src2.output)
connect(spring.flange_a, pos.flange, force_sensor.flange)
connect(spring.flange_b, force.flange, pos_sensor.flange)
connect(pos_value, pos_sensor.output)
connect(force_output, force_sensor.output)]

ODESystem(eqs, t, [], []; name, systems)
@testset "AccelerationSensor" begin
@named acc = TV.AccelerationSensor()
m = 4
@named mass = TV.Mass(m = m)
@named force = TV.Force()
@named source = Sine(frequency = 2, amplitude = 1)
@named acc_output = RealOutput()
eqs = [
connect(force.f, source.output),
connect(force.flange, mass.flange),
connect(acc.flange, mass.flange),
connect(acc_output, acc.output)
]
@named sys = ODESystem(
eqs, t, [], []; systems = [force, source, mass, acc, acc_output])
s = complete(structural_simplify(sys))
prob = ODEProblem(s, [], (0.0, pi))
sol = solve(prob, Tsit5())
@test sol[sys.acc_output.u] ≈ (sol[sys.mass.f] ./ m)
end
end

@named system = System()
s = complete(system)
sys = structural_simplify(system)
prob = ODEProblem(sys, [], (0, 1 / 400))
sol = solve(prob, Rosenbrock23())
@testset "TranslationalPosition" begin
@testset "PositionSensor & ForceSensor" begin
function mass_spring(; name)
systems = @named begin
fixed = TP.Fixed()
spring = TP.Spring(;
k = 10.0, l = 1.0, flange_a__s = 0.0, flange_b__s = 2.0)
mass = TP.Mass(; m = 100.0, s = 2.0, v = 0.0)
pos_sensor = TP.PositionSensor()
force_sensor = TP.ForceSensor()
pos_value = RealOutput()
force_value = RealOutput()
end
eqs = [
connect(fixed.flange, force_sensor.flange_a),
connect(force_sensor.flange_b, spring.flange_a),
connect(spring.flange_b, mass.flange, pos_sensor.flange),
connect(pos_sensor.output, pos_value),
connect(force_sensor.output, force_value)
]
ODESystem(eqs, t, [], []; name, systems)
end

@named model = mass_spring()
sys = structural_simplify(model)

prob = ODEProblem(sys, [], (0.0, 1.0))
sol = solve(prob, Tsit5())

@test all(sol[sys.spring.flange_a.f] .== sol[sys.force_value.u])
@test all(sol[sys.mass.s] .== sol[sys.pos_value.u])
end

delta_s = 1 / 1000
s_b = 2 - delta_s + 1

@test sol[s.pos_value.u][end]≈s_b atol=1e-3

@testset "AccelerationSensor" begin
@named acc = TV.AccelerationSensor()
m = 4
@named mass = TV.Mass(m = m)
@named force = TV.Force()
@named source = Sine(frequency = 2, amplitude = 1)
@named acc_output = RealOutput()
eqs = [
connect(force.f, source.output),
connect(force.flange, mass.flange),
connect(acc.flange, mass.flange),
connect(acc_output, acc.output)
]
@named sys = ODESystem(
eqs, t, [], []; systems = [force, source, mass, acc, acc_output])
s = complete(structural_simplify(sys))
prob = ODEProblem(s, [], (0.0, pi))
sol = solve(prob, Tsit5())
@test sol[sys.acc_output.u] ≈ (sol[sys.mass.f] ./ m)
@testset "AccelerationSensor" begin
@named acc = TP.AccelerationSensor()
m = 4
@named mass = TP.Mass(m = m)
@named force = TP.Force()
@named source = Sine(frequency = 2, amplitude = 1)
@named acc_output = RealOutput()
eqs = [
connect(force.f, source.output),
connect(force.flange, mass.flange),
connect(acc.flange, mass.flange),
connect(acc_output, acc.output)
]
@named sys = ODESystem(
eqs, t, [], []; systems = [force, source, mass, acc, acc_output])
s = complete(structural_simplify(sys))
prob = ODEProblem(s, [], (0.0, pi))
sol = solve(prob, Tsit5())
@test sol[sys.acc_output.u] ≈ (sol[sys.mass.f] ./ m)
end
end
end
2 changes: 1 addition & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const GROUP = get(ENV, "GROUP", "All")
@safetestset "Mechanical Translation" begin
include("Mechanical/translational.jl")
end
@safetestset "Mechanical Translation" begin
@safetestset "Mechanical Translation Modelica" begin
include("Mechanical/translational_modelica.jl")
end
@safetestset "Multi-Domain" begin
Expand Down
Loading