Skip to content

Commit b68eba0

Browse files
Merge pull request #392 from SebastianM-C/smc/init
Fix initialization for TranslationalPosition and add more tests
2 parents fe6bc00 + dcd6bee commit b68eba0

File tree

3 files changed

+34
-42
lines changed

3 files changed

+34
-42
lines changed

docs/src/connectors/connections.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ Now, let's consider the position-based approach. We can build the same model wi
172172
const TP = ModelingToolkitStandardLibrary.Mechanical.TranslationalPosition
173173
174174
systems = @named begin
175-
damping = TP.Damper(d = 1, va = 1, vb = 0.0)
175+
damping = TP.Damper(d = 1)
176176
body = TP.Mass(m = 1, v = 1)
177177
ground = TP.Fixed(s_0 = 0)
178178
end
@@ -191,7 +191,7 @@ nothing # hide
191191
As can be seen, we get exactly the same result. The only difference here is that we are solving an extra equation, which allows us to plot the body position as well.
192192

193193
```@example connections
194-
prob = ODEProblem(sys, [], (0, 10.0), [])
194+
prob = ODEProblem(sys, [], (0, 10.0), [], fully_determined=true)
195195
sol_p = solve(prob)
196196
197197
p1 = plot(sol_p, idxs = [body.v])
@@ -226,21 +226,21 @@ In this problem, we have a mass, spring, and damper which are connected to a fix
226226

227227
#### Damper
228228

229-
The damper will connect the flange/flange 1 (`flange_a`) to the mass, and flange/flange 2 (`flange_b`) to the fixed point. For both position- and velocity-based domains, we set the damping constant `d=1` and `va=1` and leave the default for `v_b_0` at 0. For the position domain, we also need to set the initial positions for `flange_a` and `flange_b`.
229+
The damper will connect the flange/flange 1 (`flange_a`) to the mass, and flange/flange 2 (`flange_b`) to the fixed point. For both position- and velocity-based domains, we set the damping constant `d=1` and `va=1` and leave the default for `v_b_0` at 0.
230230

231231
```@example connections
232232
@named dv = TV.Damper(d = 1)
233-
@named dp = TP.Damper(d = 1, va = 1, vb = 0.0, flange_a__s = 3, flange_b__s = 1)
233+
@named dp = TP.Damper(d = 1)
234234
nothing # hide
235235
```
236236

237237
#### Spring
238238

239-
The spring will connect the flange/flange 1 (`flange_a`) to the mass, and flange/flange 2 (`flange_b`) to the fixed point. For both position- and velocity-based domains, we set the spring constant `k=1`. The velocity domain then requires the initial velocity `va` and initial spring stretch `delta_s`. The position domain instead needs the initial positions for `flange_a` and `flange_b` and the natural spring length `l`.
239+
The spring will connect the flange/flange 1 (`flange_a`) to the mass, and flange/flange 2 (`flange_b`) to the fixed point. For both position- and velocity-based domains, we set the spring constant `k=1`. The velocity domain then requires the initial velocity `va` and initial spring stretch `delta_s`. The position domain instead needs the natural spring length `l`.
240240

241241
```@example connections
242242
@named sv = TV.Spring(k = 1)
243-
@named sp = TP.Spring(k = 1, flange_a__s = 3, flange_b__s = 1, l = 1)
243+
@named sp = TP.Spring(k = 1, l = 1)
244244
nothing # hide
245245
```
246246

@@ -281,7 +281,7 @@ function simplify_and_solve(damping, spring, body, ground; initialization_eqs =
281281
282282
println.(full_equations(sys))
283283
284-
prob = ODEProblem(sys, [], (0, 10.0), []; initialization_eqs)
284+
prob = ODEProblem(sys, [], (0, 10.0), []; initialization_eqs, fully_determined=true)
285285
sol = solve(prob; abstol = 1e-9, reltol = 1e-9)
286286
287287
return sol

src/Mechanical/TranslationalPosition/components.jl

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Flange fixed in housing at a given position.
1616
s_0 = 0
1717
end
1818
@components begin
19-
flange = Flange(; s = s_0)
19+
flange = Flange()
2020
end
2121
@equations begin
2222
flange.s ~ s_0
@@ -53,7 +53,7 @@ Sliding mass with inertia
5353
f(t)
5454
end
5555
@components begin
56-
flange = Flange(; s = s)
56+
flange = Flange()
5757
end
5858
@equations begin
5959
flange.s ~ s
@@ -65,7 +65,7 @@ end
6565

6666
const REL = Val(:relative)
6767
@component function Spring(::Val{:relative}; name, k, va = 0.0, vb = 0.0,
68-
delta_s = 0, flange_a__s = 0, flange_b__s = 0)
68+
delta_s = 0)
6969
pars = @parameters begin
7070
k = k
7171
end
@@ -87,56 +87,47 @@ const REL = Val(:relative)
8787
flange_b.f ~ -f]
8888

8989
return compose(
90-
ODESystem(eqs, t, vars, pars; name = name,
91-
defaults = [
92-
flange_a.s => flange_a__s,
93-
flange_b.s => flange_b__s,
94-
flange_a.f => +delta_s * k,
95-
flange_b.f => -delta_s * k
96-
]),
90+
ODESystem(eqs, t, vars, pars; name = name),
9791
flange_a,
9892
flange_b)
9993
end
10094

10195
const ABS = Val(:absolute)
10296

10397
"""
104-
Spring(; name, k, flange_a__s = 0, flange_b__s = 0, l=0)
98+
Spring(; name, k, l=0)
10599
106100
Linear 1D translational spring
107101
108102
# Parameters:
109103
110104
- `k`: [N/m] Spring constant
111105
- `l`: Unstretched spring length
112-
- `flange_a__s`: [m] Initial value of absolute position of flange_a
113-
- `flange_b__s`: [m] Initial value of absolute position of flange_b
114106
115107
# Connectors:
116108
117109
- `flange_a: 1-dim. translational flange on one side of spring`
118110
- `flange_b: 1-dim. translational flange on opposite side of spring` #default function
119111
"""
120-
function Spring(; name, k, flange_a__s = 0, flange_b__s = 0, l = 0)
121-
Spring(ABS; name, k, flange_a__s, flange_b__s, l)
112+
function Spring(; name, k, l = 0)
113+
Spring(ABS; name, k, l)
122114
end #default function
123115

124116
@component function Spring(::Val{:absolute};
125-
name, k, flange_a__s = 0,
126-
flange_b__s = 0, l = 0)
117+
name, k, l = 0)
127118
pars = @parameters begin
128119
k = k
129120
l = l
130121
end
131122
vars = @variables begin
132-
f(t) = k * (flange_a__s - flange_b__s - l)
123+
f(t)
133124
end
134125

135-
@named flange_a = Flange(; s = flange_a__s, f = k * (flange_a__s - flange_b__s - l))
136-
@named flange_b = Flange(; s = flange_b__s, f = -k * (flange_a__s - flange_b__s - l))
126+
@named flange_a = Flange()
127+
@named flange_b = Flange()
137128

138129
eqs = [
139-
# delta_s ~ flange_a.s - flange_b.s
130+
# delta_s ~ flange_a.s - flange_b.s
140131
f ~ k * (flange_a.s - flange_b.s - l) #delta_s
141132
flange_a.f ~ +f
142133
flange_b.f ~ -f]
@@ -166,12 +157,12 @@ Linear 1D translational damper
166157
@variables begin
167158
va(t)
168159
vb(t)
169-
f(t) = +(va - vb) * d
160+
f(t)
170161
end
171162

172163
@components begin
173-
flange_a = Flange(; s = 0.0, f = (va - vb) * d)
174-
flange_b = Flange(; s = 0.0, f = -(va - vb) * d)
164+
flange_a = Flange()
165+
flange_b = Flange()
175166
end
176167

177168
@equations begin

test/Mechanical/translational.jl

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ end
3232

3333
@testset "Spring, Damper, Mass, Fixed" begin
3434
@named dv = TV.Damper(d = 1)
35-
@named dp = TP.Damper(d = 1, va = 1, vb = 0.0, flange_a.s = 3, flange_b.s = 1)
35+
@named dp = TP.Damper(d = 1)
3636

3737
@named sv = TV.Spring(k = 1)
38-
@named sp = TP.Spring(k = 1, flange_a__s = 3, flange_b__s = 1, l = 1)
38+
@named sp = TP.Spring(k = 1, l = 1)
3939

4040
@named bv = TV.Mass(m = 1)
4141
@named bp = TP.Mass(m = 1, v = 1, s = 3)
@@ -52,7 +52,8 @@ end
5252

5353
sys = structural_simplify(model)
5454

55-
prob = ODEProblem(sys, [], (0, 20.0), []; initialization_eqs)
55+
prob = ODEProblem(
56+
sys, [], (0, 20.0), []; initialization_eqs, fully_determined = true)
5657
sol = solve(prob; abstol = 1e-9, reltol = 1e-9)
5758

5859
return sol
@@ -71,10 +72,10 @@ end
7172

7273
@testset "driven spring damper mass" begin
7374
@named dv = TV.Damper(d = 1)
74-
@named dp = TP.Damper(d = 1, va = 1.0, vb = 0.0, flange_a.s = 3, flange_b.s = 1)
75+
@named dp = TP.Damper(d = 1)
7576

7677
@named sv = TV.Spring(k = 1)
77-
@named sp = TP.Spring(k = 1, flange_a__s = 3, flange_b__s = 1, l = 1)
78+
@named sp = TP.Spring(k = 1, l = 1)
7879

7980
@named bv = TV.Mass(m = 1)
8081
@named bp = TP.Mass(m = 1, v = 1, s = 3)
@@ -101,12 +102,13 @@ end
101102

102103
model = System(dv, sv, bv, gv, fv, source)
103104
sys = structural_simplify(model)
104-
prob = ODEProblem(sys, [bv.s => 0], (0, 20.0), [])
105+
prob = ODEProblem(
106+
sys, [bv.s => 0, sv.delta_s => 1], (0, 20.0), [], fully_determined = true)
105107
solv = solve(prob, Rodas4())
106108

107109
model = System(dp, sp, bp, gp, fp, source)
108110
sys = structural_simplify(model)
109-
prob = ODEProblem(sys, [], (0, 20.0), [])
111+
prob = ODEProblem(sys, [], (0, 20.0), [], fully_determined = true)
110112
solp = solve(prob, Rodas4())
111113

112114
for sol in (solv, solp)
@@ -186,8 +188,7 @@ end
186188
function mass_spring(; name)
187189
systems = @named begin
188190
fixed = TP.Fixed()
189-
spring = TP.Spring(;
190-
k = 10.0, l = 1.0, flange_a__s = 0.0, flange_b__s = 2.0)
191+
spring = TP.Spring(; k = 10.0, l = 1.0)
191192
mass = TP.Mass(; m = 100.0, s = 2.0, v = 0.0)
192193
pos_sensor = TP.PositionSensor()
193194
force_sensor = TP.ForceSensor()
@@ -207,7 +208,7 @@ end
207208
@named model = mass_spring()
208209
sys = structural_simplify(model)
209210

210-
prob = ODEProblem(sys, [], (0.0, 1.0))
211+
prob = ODEProblem(sys, [], (0.0, 1.0), fully_determined = true)
211212
sol = solve(prob, Tsit5())
212213

213214
@test all(sol[sys.spring.flange_a.f] .== sol[sys.force_value.u])
@@ -230,7 +231,7 @@ end
230231
@named sys = ODESystem(
231232
eqs, t, [], []; systems = [force, source, mass, acc, acc_output])
232233
s = complete(structural_simplify(sys))
233-
prob = ODEProblem(s, [mass.s => 0], (0.0, pi))
234+
prob = ODEProblem(s, [mass.s => 0], (0.0, pi), fully_determined = true)
234235
sol = solve(prob, Tsit5())
235236
@test sol[sys.acc_output.u] (sol[sys.mass.f] ./ m)
236237
end

0 commit comments

Comments
 (0)