Skip to content

Commit d1e0b73

Browse files
authored
Merge pull request #120 from control-toolbox/119-dev-plot
Plot only on sol
2 parents 7b5021d + 7850171 commit d1e0b73

16 files changed

+3162
-2743
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "CTModels"
22
uuid = "34c4fa32-2049-4079-8329-de33c2a22e2d"
33
authors = ["Olivier Cots <[email protected]>"]
4-
version = "0.3.8"
4+
version = "0.3.9"
55

66
[deps]
77
CTBase = "54762871-cc72-4466-b8e8-f6c8b58076cd"

ext/default.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ function __size_plot(
6767

6868
# check what to plot
6969
do_plot_state, do_plot_costate, do_plot_control, do_plot_path, do_plot_dual = do_plot(
70+
sol,
7071
description...;
7172
state_style=state_style,
7273
control_style=control_style,

ext/plot.jl

Lines changed: 7 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ function __initial_plot(
216216

217217
# check what to plot
218218
do_plot_state, do_plot_costate, do_plot_control, do_plot_path, do_plot_dual = do_plot(
219+
sol,
219220
description...;
220221
state_style=state_style,
221222
control_style=control_style,
@@ -449,6 +450,7 @@ function __plot!(
449450

450451
# check what to plot
451452
do_plot_state, do_plot_costate, do_plot_control, do_plot_path, do_plot_dual = do_plot(
453+
sol,
452454
description...;
453455
state_style=state_style,
454456
control_style=control_style,
@@ -1040,119 +1042,14 @@ function __plot(
10401042
end
10411043

10421044
# --------------------------------------------------------------------------------------------------
1043-
# public plots: from a solution
1044-
"""
1045-
$(TYPEDSIGNATURES)
1046-
1047-
Plot the optimal control solution `sol` using the layout `layout`.
1048-
1049-
**Notes.**
1050-
1051-
- The argument `layout` can be `:group` or `:split` (default).
1052-
- `control` can be `:components`, `:norm` or `:all`.
1053-
- `time` can be `:default` or `:normalize`.
1054-
- The keyword arguments `state_style`, `control_style` and `costate_style` are passed to the `plot` function of the `Plots` package. The `state_style` is passed to the plot of the state, the `control_style` is passed to the plot of the control and the `costate_style` is passed to the plot of the costate.
1055-
"""
1056-
function Plots.plot!(
1057-
p::Plots.Plot,
1058-
sol::CTModels.Solution,
1059-
description::Symbol...;
1060-
layout::Symbol=__plot_layout(),
1061-
control::Symbol=__control_layout(),
1062-
time::Symbol=__time_normalization(),
1063-
solution_label::String=__plot_label_suffix(),
1064-
state_style::Union{NamedTuple,Symbol}=__plot_style(),
1065-
control_style::Union{NamedTuple,Symbol}=__plot_style(),
1066-
costate_style::Union{NamedTuple,Symbol}=__plot_style(),
1067-
kwargs...,
1068-
)
1069-
return __plot!(
1070-
p,
1071-
sol,
1072-
description...;
1073-
layout=layout,
1074-
control=control,
1075-
time=time,
1076-
solution_label=solution_label,
1077-
state_style=state_style,
1078-
control_style=control_style,
1079-
costate_style=costate_style,
1080-
model=nothing,
1081-
state_bounds_style=__plot_style(),
1082-
control_bounds_style=__plot_style(),
1083-
time_style=__plot_style(),
1084-
path_style=__plot_style(),
1085-
path_bounds_style=__plot_style(),
1086-
dual_style=__plot_style(),
1087-
kwargs...,
1088-
)
1089-
end
1090-
1045+
# public plots
10911046
"""
10921047
$(TYPEDSIGNATURES)
10931048
10941049
Plot the optimal control solution `sol`.
10951050
10961051
**Notes.**
10971052
1098-
- The argument `layout` can be `:group` or `:split` (default).
1099-
- The keyword arguments `state_style`, `control_style` and `costate_style` are passed to the `plot` function of the `Plots` package. The `state_style` is passed to the plot of the state, the `control_style` is passed to the plot of the control and the `costate_style` is passed to the plot of the costate.
1100-
"""
1101-
function Plots.plot(
1102-
sol::CTModels.Solution,
1103-
description::Symbol...;
1104-
layout::Symbol=__plot_layout(),
1105-
control::Symbol=__control_layout(),
1106-
time::Symbol=__time_normalization(),
1107-
solution_label::String=__plot_label_suffix(),
1108-
state_style::Union{NamedTuple,Symbol}=__plot_style(),
1109-
control_style::Union{NamedTuple,Symbol}=__plot_style(),
1110-
costate_style::Union{NamedTuple,Symbol}=__plot_style(),
1111-
size::Tuple=__size_plot(
1112-
sol,
1113-
nothing,
1114-
control,
1115-
layout,
1116-
description...;
1117-
state_style=state_style,
1118-
control_style=control_style,
1119-
costate_style=costate_style,
1120-
path_style=:none,
1121-
dual_style=:none,
1122-
),
1123-
kwargs...,
1124-
)
1125-
return __plot(
1126-
sol,
1127-
description...;
1128-
layout=layout,
1129-
control=control,
1130-
time=time,
1131-
solution_label=solution_label,
1132-
state_style=state_style,
1133-
control_style=control_style,
1134-
costate_style=costate_style,
1135-
model=nothing,
1136-
state_bounds_style=__plot_style(),
1137-
control_bounds_style=__plot_style(),
1138-
time_style=__plot_style(),
1139-
path_style=__plot_style(),
1140-
path_bounds_style=__plot_style(),
1141-
dual_style=__plot_style(),
1142-
size=size,
1143-
kwargs...,
1144-
)
1145-
end
1146-
1147-
# --------------------------------------------------------------------------------------------------
1148-
# public plots: from a solution and the model
1149-
"""
1150-
$(TYPEDSIGNATURES)
1151-
1152-
Plot the optimal control solution `sol` using the layout `layout`. The model is used to represent the initial and final times and the constraints.
1153-
1154-
**Notes.**
1155-
11561053
- The argument `layout` can be `:group` or `:split` (default).
11571054
- `control` can be `:components`, `:norm` or `:all`.
11581055
- `time` can be `:default` or `:normalize`.
@@ -1162,7 +1059,6 @@ Plot the optimal control solution `sol` using the layout `layout`. The model is
11621059
function Plots.plot!(
11631060
p::Plots.Plot,
11641061
sol::CTModels.Solution,
1165-
model::CTModels.Model,
11661062
description::Symbol...;
11671063
layout::Symbol=__plot_layout(),
11681064
control::Symbol=__control_layout(),
@@ -1192,7 +1088,7 @@ function Plots.plot!(
11921088
state_style=state_style,
11931089
control_style=control_style,
11941090
costate_style=costate_style,
1195-
model=model,
1091+
model=CTModels.model(sol),
11961092
state_bounds_style=state_bounds_style,
11971093
control_bounds_style=control_bounds_style,
11981094
time_style=time_style,
@@ -1206,7 +1102,7 @@ end
12061102
"""
12071103
$(TYPEDSIGNATURES)
12081104
1209-
Plot the optimal control solution `sol` using the layout `layout`. The model is used to represent the initial and final times and the constraints.
1105+
Plot the optimal control solution `sol`.
12101106
12111107
**Notes.**
12121108
@@ -1216,7 +1112,6 @@ Plot the optimal control solution `sol` using the layout `layout`. The model is
12161112
"""
12171113
function Plots.plot(
12181114
sol::CTModels.Solution,
1219-
model::CTModels.Model,
12201115
description::Symbol...;
12211116
layout::Symbol=__plot_layout(),
12221117
control::Symbol=__control_layout(),
@@ -1233,7 +1128,7 @@ function Plots.plot(
12331128
dual_style::Union{NamedTuple,Symbol}=__plot_style(),
12341129
size::Tuple=__size_plot(
12351130
sol,
1236-
model,
1131+
CTModels.model(sol),
12371132
control,
12381133
layout,
12391134
description...;
@@ -1255,7 +1150,7 @@ function Plots.plot(
12551150
state_style=state_style,
12561151
control_style=control_style,
12571152
costate_style=costate_style,
1258-
model=model,
1153+
model=CTModels.model(sol),
12591154
state_bounds_style=state_bounds_style,
12601155
control_bounds_style=control_bounds_style,
12611156
time_style=time_style,

ext/plot_utils.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ The description is a cleaned tuple of symbols that can be:
2626
:state, :costate, :control, :path, :dual
2727
"""
2828
function do_plot(
29+
sol::CTModels.Solution,
2930
description::Symbol...;
3031
state_style::Union{NamedTuple,Symbol},
3132
control_style::Union{NamedTuple,Symbol},
@@ -37,7 +38,7 @@ function do_plot(
3738
do_plot_costate = :costate description && costate_style != :none
3839
do_plot_control = :control description && control_style != :none
3940
do_plot_path = :path description && path_style != :none
40-
do_plot_dual = :dual description && dual_style != :none
41+
do_plot_dual = :dual description && dual_style != :none && !isnothing(CTModels.path_constraints_dual(sol))
4142

4243
return (do_plot_state, do_plot_costate, do_plot_control, do_plot_path, do_plot_dual)
4344
end

src/CTModels.jl

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -221,15 +221,6 @@ function RecipesBase.plot(sol::AbstractSolution; kwargs...)
221221
throw(CTBase.ExtensionError(:Plots))
222222
end
223223

224-
# """
225-
# $(TYPEDSIGNATURES)
226-
227-
# Plot a solution on an existing plot.
228-
# """
229-
# function RecipesBase.plot!(p::RecipesBase.AbstractPlot, sol::AbstractSolution; kwargs...)
230-
# throw(CTBase.ExtensionError(:Plots))
231-
# end
232-
233224
#
234225
include("init.jl")
235226
include("dual_model.jl")

src/solution.jl

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ function build_solution(
218218
)
219219

220220
return Solution(
221-
time_grid, times(ocp), state, control, variable, fp, objective, dual, solver_infos
221+
time_grid, times(ocp), state, control, variable, fp, objective, dual, solver_infos, ocp
222222
)
223223
end
224224

@@ -277,6 +277,7 @@ function state(
277277
<:ctNumber,
278278
<:AbstractDualModel,
279279
<:AbstractSolverInfos,
280+
<:AbstractModel,
280281
},
281282
)::TS where {TS<:Function}
282283
return value(sol.state)
@@ -334,6 +335,7 @@ function control(
334335
<:ctNumber,
335336
<:AbstractDualModel,
336337
<:AbstractSolverInfos,
338+
<:AbstractModel,
337339
},
338340
)::TS where {TS<:Function}
339341
return value(sol.control)
@@ -389,6 +391,7 @@ function variable(
389391
<:ctNumber,
390392
<:AbstractDualModel,
391393
<:AbstractSolverInfos,
394+
<:AbstractModel,
392395
},
393396
)::TS where {TS<:Union{ctNumber,ctVector}}
394397
return value(sol.variable)
@@ -416,6 +419,7 @@ function costate(
416419
<:ctNumber,
417420
<:AbstractDualModel,
418421
<:AbstractSolverInfos,
422+
<:AbstractModel,
419423
},
420424
)::Co where {Co<:Function}
421425
return sol.costate
@@ -468,6 +472,7 @@ function time_grid(
468472
<:ctNumber,
469473
<:AbstractDualModel,
470474
<:AbstractSolverInfos,
475+
<:AbstractModel,
471476
},
472477
)::T where {T<:TimesDisc}
473478
return sol.time_grid.value
@@ -490,6 +495,7 @@ function objective(
490495
O,
491496
<:AbstractDualModel,
492497
<:AbstractSolverInfos,
498+
<:AbstractModel,
493499
},
494500
)::O where {O<:ctNumber}
495501
return sol.objective
@@ -570,6 +576,7 @@ function dual_model(
570576
<:ctNumber,
571577
DM,
572578
<:AbstractSolverInfos,
579+
<:AbstractModel,
573580
},
574581
)::DM where {DM<:AbstractDualModel}
575582
return sol.dual
@@ -655,6 +662,27 @@ function variable_constraints_ub_dual(sol::Solution)
655662
return variable_constraints_ub_dual(dual_model(sol))
656663
end
657664

665+
"""
666+
$(TYPEDSIGNATURES)
667+
668+
"""
669+
function model(
670+
sol::Solution{
671+
<:AbstractTimeGridModel,
672+
<:AbstractTimesModel,
673+
<:AbstractStateModel,
674+
<:AbstractControlModel,
675+
<:AbstractVariableModel,
676+
<:Function,
677+
<:ctNumber,
678+
<:AbstractDualModel,
679+
<:AbstractSolverInfos,
680+
TM,
681+
},
682+
)::TM where {TM<:AbstractModel}
683+
return sol.model
684+
end
685+
658686
# --------------------------------------------------------------------------------------------------
659687
# print a solution
660688
"""
@@ -663,14 +691,14 @@ $(TYPEDSIGNATURES)
663691
Prints the solution.
664692
"""
665693
function Base.show(io::IO, ::MIME"text/plain", sol::Solution)
666-
return print(io, typeof(sol))
694+
return print(io, "Optimal Control Solution")
667695
end
668696

669697
"""
670698
$(TYPEDSIGNATURES)
671699
672700
"""
673701
function Base.show_default(io::IO, sol::Solution)
674-
return print(io, typeof(sol))
702+
return print(io, "Optimal Control Solution")
675703
#show(io, MIME("text/plain"), sol)
676704
end

src/types.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,7 @@ struct Solution{
490490
ObjectiveValueType<:ctNumber,
491491
DualModelType<:AbstractDualModel,
492492
SolverInfosType<:AbstractSolverInfos,
493+
ModelType<:AbstractModel,
493494
} <: AbstractSolution
494495
time_grid::TimeGridModelType
495496
times::TimesModelType
@@ -500,6 +501,7 @@ struct Solution{
500501
objective::ObjectiveValueType
501502
dual::DualModelType
502503
solver_infos::SolverInfosType
504+
model::ModelType
503505
end
504506

505507
"""

test/Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
1313
Aqua = "0.8"
1414
CTBase = "0.16"
1515
CTDirect = "0.14"
16-
CTParser = "0.2"
16+
CTParser = "0.3"
1717
JLD2 = "0.5"
1818
JSON3 = "1"
1919
NLPModelsIpopt = "0.10"

0 commit comments

Comments
 (0)