Skip to content

Commit 77f3cc6

Browse files
Merge pull request #303 from sathvikbhagavan/sb/tpsensors
feat: add sensors in TranslationalPosition
2 parents b6c7cd2 + f317451 commit 77f3cc6

File tree

5 files changed

+205
-57
lines changed

5 files changed

+205
-57
lines changed

src/Mechanical/Translational/sensors.jl

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""
22
ForceSensor(; name)
33
4-
Linear 1D force input sensor.
4+
Linear 1D force sensor, measures the force between two flanges.
55
66
# Connectors:
77
@@ -10,19 +10,22 @@ Linear 1D force input sensor.
1010
"""
1111
@mtkmodel ForceSensor begin
1212
@components begin
13-
flange = MechanicalPort()
13+
flange_a = MechanicalPort()
14+
flange_b = MechanicalPort()
1415
output = RealOutput()
1516
end
1617

1718
@equations begin
18-
flange.f ~ -output.u
19+
flange_a.v ~ flange_b.v
20+
flange_a.f + flange_b.f ~ 0.0
21+
output.u ~ flange_a.f
1922
end
2023
end
2124

2225
"""
2326
PositionSensor(; s = 0, name)
2427
25-
Linear 1D position input sensor.
28+
Linear 1D position sensor.
2629
2730
# States:
2831
@@ -53,7 +56,7 @@ end
5356
"""
5457
AccelerationSensor(; name)
5558
56-
Linear 1D position input sensor.
59+
Linear 1D acceleration sensor.
5760
5861
# States:
5962

src/Mechanical/TranslationalPosition/TranslationalPosition.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,7 @@ include("components.jl")
1616
export Force
1717
include("sources.jl")
1818

19+
export PositionSensor, ForceSensor, AccelerationSensor
20+
include("sensors.jl")
21+
1922
end
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
"""
2+
ForceSensor(; name)
3+
4+
Linear 1D force sensor, measures the force between two flanges.
5+
6+
# Connectors:
7+
8+
- `flange_a`: 1-dim. translational flange
9+
- `flange_b`: 1-dim. translational flange
10+
- `output`: real output
11+
"""
12+
@mtkmodel ForceSensor begin
13+
@components begin
14+
flange_a = Flange()
15+
flange_b = Flange()
16+
output = RealOutput()
17+
end
18+
19+
@equations begin
20+
flange_a.s ~ flange_b.s
21+
flange_a.f + flange_b.f ~ 0.0
22+
output.u ~ flange_a.f
23+
end
24+
end
25+
26+
"""
27+
PositionSensor(; s = 0, name)
28+
29+
Linear 1D position sensor.
30+
31+
# States:
32+
33+
- `s`: [m] absolute position (with initial value of 0.0)
34+
35+
# Connectors:
36+
37+
- `flange`: 1-dim. translational flange
38+
- `output`: real output
39+
"""
40+
@mtkmodel PositionSensor begin
41+
@components begin
42+
flange = Flange()
43+
output = RealOutput()
44+
end
45+
46+
@equations begin
47+
output.u ~ flange.s
48+
flange.f ~ 0.0
49+
end
50+
end
51+
52+
"""
53+
AccelerationSensor(; name)
54+
55+
Linear 1D acceleration sensor.
56+
57+
# States:
58+
59+
- `a`: [m/s^2] measured acceleration
60+
61+
# Connectors:
62+
63+
- `flange`: 1-dim. translational flange
64+
- `output`: real output
65+
"""
66+
@mtkmodel AccelerationSensor begin
67+
@components begin
68+
flange = Flange()
69+
output = RealOutput()
70+
end
71+
72+
@variables begin
73+
a(t) = 0.0
74+
end
75+
76+
@equations begin
77+
a ~ D(D(flange.s))
78+
output.u ~ a
79+
flange.f ~ 0.0
80+
end
81+
end

test/Mechanical/translational.jl

Lines changed: 112 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -115,61 +115,122 @@ end
115115
end
116116

117117
@testset "sources & sensors" begin
118-
function System(; name)
119-
systems = @named begin
120-
pos = TV.Position()
121-
pos_sensor = TV.PositionSensor(; s = 1)
122-
force = TV.Force()
123-
force_sensor = TV.ForceSensor()
124-
125-
spring = TV.Spring(; k = 1000)
126-
127-
src1 = Sine(frequency = 100, amplitude = 2)
128-
src2 = Sine(frequency = 100, amplitude = -1)
129-
130-
pos_value = RealInput()
131-
force_output = RealOutput()
118+
@testset "Translational" begin
119+
@testset "PositionSensor & ForceSensor" begin
120+
function System(; name)
121+
systems = @named begin
122+
pos = TV.Position()
123+
pos_sensor = TV.PositionSensor(; s = 1)
124+
force = TV.Force()
125+
force_sensor = TV.ForceSensor()
126+
127+
spring = TV.Spring(; k = 1000)
128+
129+
src1 = Sine(frequency = 100, amplitude = 2)
130+
src2 = Sine(frequency = 100, amplitude = -1)
131+
132+
pos_value = RealInput()
133+
force_output = RealOutput()
134+
end
135+
136+
eqs = [connect(pos.s, src1.output)
137+
connect(force.f, src2.output)
138+
connect(pos.flange, force_sensor.flange_a)
139+
connect(force_sensor.flange_b, spring.flange_a)
140+
connect(spring.flange_b, force.flange, pos_sensor.flange)
141+
connect(pos_value, pos_sensor.output)
142+
connect(force_output, force_sensor.output)]
143+
144+
ODESystem(eqs, t, [], []; name, systems)
145+
end
146+
147+
@named system = System()
148+
s = complete(system)
149+
sys = structural_simplify(system)
150+
prob = ODEProblem(sys, [], (0, 1 / 400))
151+
sol = solve(prob, Rosenbrock23())
152+
153+
delta_s = 1 / 1000
154+
s_b = 2 - delta_s + 1
155+
156+
@test sol[s.pos_value.u][end]s_b atol=1e-3
157+
@test all(sol[s.spring.flange_a.f] .== sol[s.force_output.u])
132158
end
133159

134-
eqs = [connect(pos.s, src1.output)
135-
connect(force.f, src2.output)
136-
connect(spring.flange_a, pos.flange, force_sensor.flange)
137-
connect(spring.flange_b, force.flange, pos_sensor.flange)
138-
connect(pos_value, pos_sensor.output)
139-
connect(force_output, force_sensor.output)]
140-
141-
ODESystem(eqs, t, [], []; name, systems)
160+
@testset "AccelerationSensor" begin
161+
@named acc = TV.AccelerationSensor()
162+
m = 4
163+
@named mass = TV.Mass(m = m)
164+
@named force = TV.Force()
165+
@named source = Sine(frequency = 2, amplitude = 1)
166+
@named acc_output = RealOutput()
167+
eqs = [
168+
connect(force.f, source.output),
169+
connect(force.flange, mass.flange),
170+
connect(acc.flange, mass.flange),
171+
connect(acc_output, acc.output)
172+
]
173+
@named sys = ODESystem(
174+
eqs, t, [], []; systems = [force, source, mass, acc, acc_output])
175+
s = complete(structural_simplify(sys))
176+
prob = ODEProblem(s, [], (0.0, pi))
177+
sol = solve(prob, Tsit5())
178+
@test sol[sys.acc_output.u] (sol[sys.mass.f] ./ m)
179+
end
142180
end
143181

144-
@named system = System()
145-
s = complete(system)
146-
sys = structural_simplify(system)
147-
prob = ODEProblem(sys, [], (0, 1 / 400))
148-
sol = solve(prob, Rosenbrock23())
182+
@testset "TranslationalPosition" begin
183+
@testset "PositionSensor & ForceSensor" begin
184+
function mass_spring(; name)
185+
systems = @named begin
186+
fixed = TP.Fixed()
187+
spring = TP.Spring(;
188+
k = 10.0, l = 1.0, flange_a__s = 0.0, flange_b__s = 2.0)
189+
mass = TP.Mass(; m = 100.0, s = 2.0, v = 0.0)
190+
pos_sensor = TP.PositionSensor()
191+
force_sensor = TP.ForceSensor()
192+
pos_value = RealOutput()
193+
force_value = RealOutput()
194+
end
195+
eqs = [
196+
connect(fixed.flange, force_sensor.flange_a),
197+
connect(force_sensor.flange_b, spring.flange_a),
198+
connect(spring.flange_b, mass.flange, pos_sensor.flange),
199+
connect(pos_sensor.output, pos_value),
200+
connect(force_sensor.output, force_value)
201+
]
202+
ODESystem(eqs, t, [], []; name, systems)
203+
end
204+
205+
@named model = mass_spring()
206+
sys = structural_simplify(model)
207+
208+
prob = ODEProblem(sys, [], (0.0, 1.0))
209+
sol = solve(prob, Tsit5())
210+
211+
@test all(sol[sys.spring.flange_a.f] .== sol[sys.force_value.u])
212+
@test all(sol[sys.mass.s] .== sol[sys.pos_value.u])
213+
end
149214

150-
delta_s = 1 / 1000
151-
s_b = 2 - delta_s + 1
152-
153-
@test sol[s.pos_value.u][end]s_b atol=1e-3
154-
155-
@testset "AccelerationSensor" begin
156-
@named acc = TV.AccelerationSensor()
157-
m = 4
158-
@named mass = TV.Mass(m = m)
159-
@named force = TV.Force()
160-
@named source = Sine(frequency = 2, amplitude = 1)
161-
@named acc_output = RealOutput()
162-
eqs = [
163-
connect(force.f, source.output),
164-
connect(force.flange, mass.flange),
165-
connect(acc.flange, mass.flange),
166-
connect(acc_output, acc.output)
167-
]
168-
@named sys = ODESystem(
169-
eqs, t, [], []; systems = [force, source, mass, acc, acc_output])
170-
s = complete(structural_simplify(sys))
171-
prob = ODEProblem(s, [], (0.0, pi))
172-
sol = solve(prob, Tsit5())
173-
@test sol[sys.acc_output.u] (sol[sys.mass.f] ./ m)
215+
@testset "AccelerationSensor" begin
216+
@named acc = TP.AccelerationSensor()
217+
m = 4
218+
@named mass = TP.Mass(m = m)
219+
@named force = TP.Force()
220+
@named source = Sine(frequency = 2, amplitude = 1)
221+
@named acc_output = RealOutput()
222+
eqs = [
223+
connect(force.f, source.output),
224+
connect(force.flange, mass.flange),
225+
connect(acc.flange, mass.flange),
226+
connect(acc_output, acc.output)
227+
]
228+
@named sys = ODESystem(
229+
eqs, t, [], []; systems = [force, source, mass, acc, acc_output])
230+
s = complete(structural_simplify(sys))
231+
prob = ODEProblem(s, [], (0.0, pi))
232+
sol = solve(prob, Tsit5())
233+
@test sol[sys.acc_output.u] (sol[sys.mass.f] ./ m)
234+
end
174235
end
175236
end

test/runtests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ const GROUP = get(ENV, "GROUP", "All")
6363
@safetestset "Mechanical Translation" begin
6464
include("Mechanical/translational.jl")
6565
end
66-
@safetestset "Mechanical Translation" begin
66+
@safetestset "Mechanical Translation Modelica" begin
6767
include("Mechanical/translational_modelica.jl")
6868
end
6969
@safetestset "Multi-Domain" begin

0 commit comments

Comments
 (0)