1+ """
2+ $(TYPEDSIGNATURES)
3+
4+ Used to set the default value of the name of the time.
5+ The default value is `t`.
6+ """
7+ __time_name ():: String = " t"
8+
9+ """
10+ $(TYPEDSIGNATURES)
11+
12+ """
13+ __is_times_set (ocp:: OptimalControlModelMutable ):: Bool = ! ismissing (ocp. times)
14+
15+ """
16+ $(TYPEDSIGNATURES)
17+
18+ Set the initial and final times. We denote by t0 the initial time and tf the final time.
19+ The optimal control problem is denoted ocp.
20+ When a time is free, then, one must provide the corresponding index of the ocp variable.
21+
22+ !!! note
23+
24+ You must use time! only once to set either the initial or the final time, or both.
25+
26+ # Examples
27+
28+ ```@example
29+ julia> time!(ocp, t0=0, tf=1 ) # Fixed t0 and fixed tf
30+ julia> time!(ocp, t0=0, indf=2) # Fixed t0 and free tf
31+ julia> time!(ocp, ind0=2, tf=1 ) # Free t0 and fixed tf
32+ julia> time!(ocp, ind0=2, indf=3) # Free t0 and free tf
33+ ```
34+
35+ When you plot a solution of an optimal control problem, the name of the time variable appears.
36+ By default, the name is "t".
37+ Consider you want to set the name of the time variable to "s".
38+
39+ ```@example
40+ julia> time!(ocp, t0=0, tf=1, name="s") # name is a String
41+ # or
42+ julia> time!(ocp, t0=0, tf=1, name=:s ) # name is a Symbol
43+ ```
44+ """
45+ function time! (
46+ ocp:: OptimalControlModelMutable ;
47+ t0:: Union{Time, Nothing} = nothing ,
48+ tf:: Union{Time, Nothing} = nothing ,
49+ ind0:: Union{Int, Nothing} = nothing ,
50+ indf:: Union{Int, Nothing} = nothing ,
51+ time_name:: Union{String, Symbol} = __time_name (),
52+ ):: Nothing
53+
54+ # check if the function has been already called
55+ __is_times_set (ocp) && throw (CTBase. UnauthorizedCall (" the time has already been set." ))
56+
57+ # If t0 or tf is free, check if the problem has a variable set
58+ # and in this case check consistency, meaning that ind0 and indf must belong
59+ # to 1 <= ind0, indf <= q, where q is the variable dimension.
60+ # Otherwise, throw an error.
61+ (! isnothing (ind0) || ! isnothing (indf)) && ! __is_variable_set (ocp) &&
62+ throw (CTBase. UnauthorizedCall (" the variable must be set before calling time! if t0 or tf is free." ))
63+
64+ # check consistency with the variable
65+ if __is_variable_set (ocp)
66+ q = dimension (ocp. variable)
67+
68+ ! isnothing (ind0) && ! (1 ≤ ind0 ≤ q) && # t0 is free
69+ throw (CTBase. IncorrectArgument (" the index of the t0 variable must be contained in 1:$q " ))
70+
71+ ! isnothing (indf) && ! (1 ≤ indf ≤ q) && # tf is free
72+ throw (CTBase. IncorrectArgument (" the index of the tf variable must be contained in 1:$q " ))
73+ end
74+
75+ # check consistency
76+ ! isnothing (t0) &&
77+ ! isnothing (ind0) &&
78+ throw (
79+ CTBase. IncorrectArgument (
80+ " Providing t0 and ind0 has no sense. The initial time cannot be fixed and free." ,
81+ ),
82+ )
83+ isnothing (t0) &&
84+ isnothing (ind0) &&
85+ throw (
86+ CTBase. IncorrectArgument (
87+ " Please either provide the value of the initial time t0 (if fixed) or its index in the variable of ocp (if free)." ,
88+ ),
89+ )
90+ ! isnothing (tf) &&
91+ ! isnothing (indf) &&
92+ throw (
93+ CTBase. IncorrectArgument (
94+ " Providing tf and indf has no sense. The final time cannot be fixed and free." ,
95+ ),
96+ )
97+ isnothing (tf) &&
98+ isnothing (indf) &&
99+ throw (
100+ CTBase. IncorrectArgument (
101+ " Please either provide the value of the final time tf (if fixed) or its index in the variable of ocp (if free)." ,
102+ ),
103+ )
104+
105+ #
106+ time_name = time_name isa String ? time_name : string (time_name)
107+
108+ # core
109+ (initial_time, final_time) = @match (t0, ind0, tf, indf) begin
110+ (:: Time , :: Nothing , :: Time , :: Nothing ) => begin # (t0, tf)
111+ (FixedTimeModel (t0, t0 isa Int ? string (t0) : string (round (t0, digits = 2 ))),
112+ FixedTimeModel (tf, tf isa Int ? string (tf) : string (round (tf, digits = 2 ))))
113+ end
114+ (:: Nothing , :: Int , :: Time , :: Nothing ) => begin # (ind0, tf)
115+ (FreeTimeModel (ind0, components (ocp. variable)[ind0]),
116+ FixedTimeModel (tf, tf isa Int ? string (tf) : string (round (tf, digits = 2 ))))
117+ end
118+ (:: Time , :: Nothing , :: Nothing , :: Int ) => begin # (t0, indf)
119+ (FixedTimeModel (t0, t0 isa Int ? string (t0) : string (round (t0, digits = 2 ))),
120+ FreeTimeModel (indf, components (ocp. variable)[indf]))
121+ end
122+ (:: Nothing , :: Int , :: Nothing , :: Int ) => begin # (ind0, indf)
123+ (FreeTimeModel (ind0, components (ocp. variable)[ind0]),
124+ FreeTimeModel (indf, components (ocp. variable)[indf]))
125+ end
126+ _ => throw (CTBase. IncorrectArgument (" Provided arguments are inconsistent." ))
127+ end
128+
129+ ocp. times = TimesModel (initial_time, final_time, time_name)
130+ return nothing
131+ end
132+
133+ # ------------------------------------------------------------------------------ #
134+ # GETTERS
135+ # ------------------------------------------------------------------------------ #
136+
137+ # From FixedTimeModel
138+ time (model:: FixedTimeModel ):: Time = model. time
139+ name (model:: FixedTimeModel ):: String = model. name
140+
141+ # From FreeTimeModel
142+ index (model:: FreeTimeModel ):: Int = model. index
143+ name (model:: FreeTimeModel ):: String = model. name
144+ function time (model:: FreeTimeModel , variable:: ctNumber ):: Time
145+ # check if model.index = 1
146+ ! (model. index == 1 ) && throw (CTBase. IncorrectArgument (" the index of the time variable must be 1." ))
147+ return variable
148+ end
149+ function time (model:: FreeTimeModel , variable:: AbstractVector{<:ctNumber} ):: Time
150+ # check if model.index in [1, length(variable)]
151+ ! (1 ≤ model. index ≤ length (variable)) && throw (CTBase. IncorrectArgument (" the index of the time variable must be contained in 1:$(length (variable)) " ))
152+ return variable[model. index]
153+ end
154+
155+ # From TimesModel
156+ (initial (model:: TimesModel{TI, TF} ):: TI ) where {TI <: AbstractTimeModel , TF <: AbstractTimeModel } = model. initial
157+ (final (model:: TimesModel{TI, TF} ):: TF ) where {TI <: AbstractTimeModel , TF <: AbstractTimeModel } = model. final
158+ time_name (model:: TimesModel ):: String = model. time_name
159+ initial_time (model:: TimesModel{FixedTimeModel, <:AbstractTimeModel} ):: Time = time (initial (model))
160+ final_time (model:: TimesModel{<:AbstractTimeModel, FixedTimeModel} ):: Time = time (final (model))
161+ initial_time (model:: TimesModel{FreeTimeModel, <:AbstractTimeModel} , variable:: Variable ):: Time = time (initial (model), variable)
162+ final_time (model:: TimesModel{<:AbstractTimeModel, FreeTimeModel} , variable:: Variable ):: Time = time (final (model), variable)
163+
164+ # From OptimalControlModel
165+ (times (model:: OptimalControlModel{T, S, C, V} ):: T ) where {
166+ T<: AbstractTimesModel ,
167+ S<: AbstractStateModel ,
168+ C<: AbstractControlModel ,
169+ V<: AbstractVariableModel } = model. times
170+ time_name (model:: OptimalControlModel ):: String = time_name (times (model))
171+ (initial_time (model:: OptimalControlModel{T, S, C, V} ):: Time ) where {
172+ T<: TimesModel{FixedTimeModel, <:AbstractTimeModel} ,
173+ S<: AbstractStateModel ,
174+ C<: AbstractControlModel ,
175+ V<: AbstractVariableModel } = initial_time (times (model))
176+ (final_time (model:: OptimalControlModel{T, S, C, V} ):: Time ) where {
177+ T<: TimesModel{<:AbstractTimeModel, FixedTimeModel} ,
178+ S<: AbstractStateModel ,
179+ C<: AbstractControlModel ,
180+ V<: AbstractVariableModel } = final_time (times (model))
181+ (initial_time (model:: OptimalControlModel{T, S, C, V} , variable:: Variable ):: Time ) where {
182+ T<: TimesModel{FreeTimeModel, <:AbstractTimeModel} ,
183+ S<: AbstractStateModel ,
184+ C<: AbstractControlModel ,
185+ V<: AbstractVariableModel } = initial_time (times (model), variable)
186+ (final_time (model:: OptimalControlModel{T, S, C, V} , variable:: Variable ):: Time ) where {
187+ T<: TimesModel{<:AbstractTimeModel, FreeTimeModel} ,
188+ S<: AbstractStateModel ,
189+ C<: AbstractControlModel ,
190+ V<: AbstractVariableModel } = final_time (times (model), variable)
191+ initial_time_name (model:: OptimalControlModel ):: String = name (initial (times (model)))
192+ final_time_name (model:: OptimalControlModel ):: String = name (final (times (model)))
0 commit comments