1+ # Define and register smooth functions
2+ # These are "smooth" aka differentiable and avoid Gibbs effect
3+ # These follow: `offset` + `smooth_wave` * `smooth_step` with zero output for `t < start_time`
4+ function smooth_cos (x, δ, f, amplitude, ϕ, offset, start_time)
5+ offset + amplitude * cos (2 * π* f* (x - start_time) + ϕ) * smooth_step (x, δ, one (x), zero (x), start_time)
6+ end
7+
8+ function smooth_damped_sin (x, δ, f, amplitude, damping, ϕ, offset, start_time)
9+ offset + exp ((start_time - x)* damping)* amplitude* sin (2 * π* f* (x - start_time) + ϕ) * smooth_step (x, δ, one (x), zero (x), start_time)
10+ end
11+
12+ function smooth_ramp (x, δ, height, duration, offset, start_time)
13+ offset + height/ (duration) * (smooth_xH (x, δ, start_time) - smooth_xH (x, δ, start_time+ duration))
14+ end
15+
16+ function smooth_sin (x, δ, f, amplitude, ϕ, offset, start_time)
17+ offset + amplitude * sin (2 * pi * f* (x - start_time) + ϕ) * smooth_step (x, δ, one (x), zero (x), start_time)
18+ end
19+
20+ function smooth_square (x, δ, f, amplitude, offset, start_time)
21+ offset + amplitude* 2 atan (sin (2 π* (x - start_time)* f)/ δ)/ π * smooth_step (x, δ, one (x), zero (x), start_time)
22+ end
23+
24+ function smooth_step (x, δ, height, offset, start_time)
25+ offset + height* (atan ((x - start_time)/ δ)/ π + 0.5 )
26+ end
27+
28+ function smooth_triangular (x, δ, f, amplitude, offset, start_time)
29+ offset + amplitude * (1 - 2 acos ((1 - δ)sin (2 π* (x - start_time)* f))/ π) * smooth_step (x, δ, one (x), zero (x), start_time)
30+ end
31+
32+ function smooth_xH (x, δ, tₒ)
33+ 0.5 * (x- tₒ) * (1 + ((x- tₒ)/ sqrt ((x- tₒ)^ 2 + δ^ 2 )))
34+ end
35+
36+ function square (x, f, amplitude, offset, start_time)
37+ offset + (x > start_time) * (amplitude * (4 * floor (f* (x - start_time)) - 2 * floor (2 * (x - start_time)* f) + 1 ))
38+ end
39+
40+ function triangular (x, f, amplitude, offset, start_time)
41+ p = 1 / f # period
42+ offset + (x > start_time) * (4 * amplitude * f * abs (abs ((x - p/ 4 - start_time) % p) - p/ 2 ) - amplitude)
43+ end
44+
145"""
246Generate constant signal.
347
@@ -22,25 +66,36 @@ Generate sine signal.
2266# Parameters:
2367- `frequency`: [Hz] Frequency of sine wave
2468- `amplitude`: Amplitude of sine wave
25- - `phase`: [rad] Phase of sine wave
69+ - `phase`: [rad] Phase of sine wave
2670- `offset`: Offset of output signal
2771- `start_time`: [s] Output `y = offset` for `t < start_time`
72+ - `smooth`: If `true`, returns a smooth wave. Defaults to `false`
73+ It uses a smoothing factor of `δ=1e-5`
2874
2975# Connectors:
3076- `output`
3177"""
32- function Sine (;name,
33- frequency,
78+ function Sine (;name,
79+ frequency,
3480 amplitude= 1 ,
3581 phase= 0 ,
3682 offset= 0 ,
37- start_time= 0 )
83+ start_time= 0 ,
84+ smooth= false )
3885
3986 @named output = RealOutput ()
4087 pars = @parameters offset= offset start_time= start_time amplitude= amplitude frequency= frequency phase= phase
88+ equation = if smooth == false
89+ offset + ifelse (t < start_time, 0 , amplitude* sin (2 * pi * frequency* (t - start_time) + phase))
90+ else
91+ δ = 1e-5
92+ smooth_sin (t, δ, frequency, amplitude, phase, offset, start_time)
93+ end
94+
4195 eqs = [
42- output. u ~ offset + ifelse (t < start_time, 0 , amplitude * sin ( 2 * pi * frequency * (t - start_time) + phase))
96+ output. u ~ equation
4397 ]
98+
4499 compose (ODESystem (eqs, t, [], pars; name= name), [output])
45100end
46101
@@ -50,32 +105,43 @@ Generate cosine signal.
50105# Parameters:
51106- `frequency`: [Hz] Frequency of sine wave
52107- `amplitude`: Amplitude of sine wave
53- - `phase`: [rad] Phase of sine wave
108+ - `phase`: [rad] Phase of sine wave
54109- `offset`: Offset of output signal
55110- `start_time`: [s] Output `y = offset` for `t < start_time`
111+ - `smooth`: If `true`, returns a smooth wave. Defaults to `false`
112+ It uses a smoothing factor of `δ=1e-5`
56113
57114# Connectors:
58115- `output`
59116"""
60- function Cosine (;name,
61- frequency,
117+
118+ function Cosine (;name,
119+ frequency,
62120 amplitude= 1 ,
63121 phase= 0 ,
64122 offset= 0 ,
65- start_time= 0 )
123+ start_time= 0 ,
124+ smooth= false )
66125
67126 @named output = RealOutput ()
68127 pars = @parameters offset= offset start_time= start_time amplitude= amplitude frequency= frequency phase= phase
128+ equation = if smooth == false
129+ offset + ifelse (t < start_time, zero (t), amplitude* cos (2 * pi * frequency* (t - start_time) + phase))
130+ else
131+ δ = 1e-5
132+ smooth_cos (t, δ, frequency, amplitude, phase, offset, start_time)
133+ end
69134 eqs = [
70- output. u ~ offset + ifelse (t < start_time, 0 , amplitude * cos ( 2 * pi * frequency * (t - start_time) + phase))
135+ output. u ~ equation
71136 ]
137+
72138 compose (ODESystem (eqs, t, [], pars; name= name), [output])
73139end
74140
75141"""
76142Generate current time signal.
77143
78- # Parameters:
144+ # Parameters:
79145- `offset`: Offset of output signal
80146- `start_time`: [s] Output `y = offset` for `t < start_time`
81147
@@ -86,8 +152,9 @@ function ContinuousClock(;name, offset=0, start_time=0)
86152 @named output = RealOutput ()
87153 pars = @parameters offset= offset start_time= start_time
88154 eqs = [
89- output. u ~ offset + ifelse (t < start_time, 0 , t - start_time)
155+ output. u ~ offset + ifelse (t < start_time, zero (t) , t - start_time)
90156 ]
157+
91158 compose (ODESystem (eqs, t, [], pars; name= name), [output])
92159end
93160
@@ -99,22 +166,73 @@ Generate ramp signal.
99166- `duration`: [s] Duration of ramp (= 0.0 gives a Step)
100167- `offset`: Offset of output signal
101168- `start_time`: [s] Output `y = offset` for `t < start_time`
169+ - `smooth`: If `true`, returns a smooth wave. Defaults to `false`
170+ It uses a smoothing factor of `δ=1e-5`
102171
103172# Connectors:
104173- `output`
105174"""
106- function Ramp (;name,
107- offset= 0 ,
175+ function Ramp (;name,
108176 height= 1 ,
109- duration= 1 ,
110- start_time= 0 )
177+ duration= 1 ,
178+ offset= 0 ,
179+ start_time= 0 ,
180+ smooth= false )
111181
112182 @named output = RealOutput ()
113183 pars = @parameters offset= offset start_time= start_time height= height duration= duration
114- eqs = [
115- output . u ~ offset + ifelse (t < start_time, 0 ,
184+ equation = if smooth == false
185+ offset + ifelse (t < start_time, 0 ,
116186 ifelse (t < (start_time + duration), (t - start_time) * height / duration, height))
187+ else
188+ δ = 1e-5
189+ smooth_ramp (t, δ, height, duration, offset, start_time)
190+ end
191+
192+ eqs = [
193+ output. u ~ equation
194+ ]
195+
196+ compose (ODESystem (eqs, t, [], pars; name= name), [output])
197+ end
198+
199+ """
200+ Generate smooth square signal.
201+
202+ # Parameters:
203+ - `frequency`: [Hz] Frequency of square wave
204+ - `amplitude`: Amplitude of square wave
205+ - `offset`: Offset of output signal
206+ - `start_time`: [s] Output `y = offset` for `t < start_time`
207+ - `smooth`: If `true`, returns a smooth wave. Defaults to `false`
208+ It uses a smoothing factor of `δ=1e-5`
209+
210+ # Connectors:
211+ - `output`
212+ """
213+ function Square (; name, frequency= 1.0 , amplitude= 1.0 ,
214+ offset= 0.0 , start_time= 0.0 , smooth= false )
215+ δ = 1e-5
216+
217+ @named output = RealOutput ()
218+ pars = @parameters begin
219+ frequency= frequency
220+ amplitude= amplitude
221+ offset= offset
222+ start_time= start_time
223+ end
224+
225+ equation = if smooth == false
226+ square (t, frequency, amplitude, offset, start_time)
227+ else
228+ δ = 1e-5
229+ smooth_square (t, δ, frequency, amplitude, offset, start_time)
230+ end
231+
232+ eqs = [
233+ output. u ~ equation
117234 ]
235+
118236 compose (ODESystem (eqs, t, [], pars; name= name), [output])
119237end
120238
@@ -125,16 +243,26 @@ Generate step signal.
125243- `height`: Height of step
126244- `offset`: Offset of output signal
127245- `start_time`: [s] Output `y = offset` for `t < start_time`
246+ - `smooth`: If `true`, returns a smooth wave. Defaults to `false`
247+ It uses a smoothing factor of `δ=1e-5`
128248
129249# Connectors:
130250- `output`
131251"""
132- function Step (;name, offset = 0 , height = 1 , start_time= 0 )
252+ function Step (;name, height = 1 , offset = 0 , start_time= 0 , smooth = true )
133253 @named output = RealOutput ()
134254 pars = @parameters offset= offset start_time= start_time height= height
255+ equation = if smooth == false
256+ offset + ifelse (t < start_time, zero (t), height)
257+ else
258+ δ = 1e-5
259+ smooth_step (t, δ, height, offset, start_time)
260+ end
261+
135262 eqs = [
136- output. u ~ offset + ifelse (t < start_time, 0 , height)
263+ output. u ~ equation
137264 ]
265+
138266 compose (ODESystem (eqs, t, [], pars; name= name), [output])
139267end
140268
@@ -145,26 +273,77 @@ Generate exponentially damped sine signal.
145273- `frequency`: [Hz] Frequency of sine wave
146274- `amplitude`: Amplitude of sine wave
147275- `damping`: [1/s] Damping coefficient of sine wave
148- - `phase`: [rad] Phase of sine wave
276+ - `phase`: [rad] Phase of sine wave
149277- `offset`: Offset of output signal
150278- `start_time`: [s] Output `y = offset` for `t < start_time`
279+ - `smooth`: If `true`, returns a smooth wave. Defaults to `false`
280+ It uses a smoothing factor of `δ=1e-5`
151281
152282# Connectors:
153283- `output`
154284"""
155- function ExpSine (;name,
156- frequency,
285+ function ExpSine (; name,
286+ frequency,
157287 amplitude= 1 ,
158288 damping= 0.1 ,
159289 phase= 0 ,
160290 offset= 0 ,
161- start_time= 0 )
291+ start_time= 0 ,
292+ smooth= false )
162293
163294 @named output = RealOutput ()
164295 pars = @parameters offset= offset start_time= start_time amplitude= amplitude frequency= frequency phase= phase damping= damping
296+
297+ equation = if smooth == false
298+ offset + ifelse (t < start_time, 0 , amplitude * exp (- damping * (t - start_time)) * sin (2 * pi * frequency* (t - start_time) + phase))
299+ else
300+ δ = 1e-5
301+ smooth_damped_sin (t, δ, frequency, amplitude, damping, phase, offset, start_time)
302+ end
303+
165304 eqs = [
166- output. u ~ offset + ifelse (t < start_time, 0 , amplitude * exp ( - damping * (t - start_time)) * sin ( 2 * pi * frequency * (t - start_time) + phase))
305+ output. u ~ equation
167306 ]
307+
308+ compose (ODESystem (eqs, t, [], pars; name= name), [output])
309+ end
310+
311+ """
312+ Generate smooth triangular signal for frequencies less than or equal to 25 Hz
313+
314+ # Parameters:
315+ - `frequency`: [Hz] Frequency of square wave
316+ - `amplitude`: Amplitude of square wave
317+ - `offset`: Offset of output signal.
318+ - `start_time`: [s] Output `y = offset` for `t < start_time`
319+ - `smooth`: If `true`, returns a smooth wave. Defaults to `false`
320+ It uses a smoothing factor of `δ=1e-5`
321+
322+ # Connectors:
323+ - `output`
324+ """
325+ function Triangular (; name, amplitude= 1.0 , frequency= 1.0 ,
326+ offset= 0.0 , start_time= 0.0 , smooth= false )
327+
328+ @named output = RealOutput ()
329+ pars = @parameters begin
330+ amplitude= amplitude
331+ frequency= frequency
332+ offset= offset
333+ start_time= start_time
334+ end
335+
336+ equation = if smooth == false
337+ triangular (t, frequency, amplitude, offset, start_time)
338+ else
339+ δ = 1e-5
340+ smooth_triangular (t, δ, frequency, amplitude, offset, start_time)
341+ end
342+
343+ eqs = [
344+ output. u ~ equation
345+ ]
346+
168347 compose (ODESystem (eqs, t, [], pars; name= name), [output])
169348end
170349
0 commit comments