Skip to content

double pendulum, added variable bounds#541

Closed
Peter230655 wants to merge 1 commit into
csu-hmc:masterfrom
Peter230655:pendulum-with-bounds
Closed

double pendulum, added variable bounds#541
Peter230655 wants to merge 1 commit into
csu-hmc:masterfrom
Peter230655:pendulum-with-bounds

Conversation

@Peter230655

Copy link
Copy Markdown
Contributor

As suggested I took the existing double pendulum and added variable bounds.

Interesting:
It is best to start with the final position upright at rest, and use its solution as initial guess for the problem with variable bounds.
Using a solution with variable bounds to find a solution with different variable bounds make iterate for an hour or more.

@moorepants

Copy link
Copy Markdown
Member

You state the goal is to get the pendulum "approximately upright" but I'm not sure that gives an optimal control problem with a global minimum, i.e. there is no unique solution to the problem.

@Peter230655

Copy link
Copy Markdown
Contributor Author

By "approximately upright" I meant the final state must be anywhere within the bounds preset by the variable bounds.
My intuition is, that the optimum solution must be at the edges of one of the bounds, so that balance varaibles are within the bounds.
Here the q_2, q_3 are at the edges, the u_2, u_3 and the accelerations are within the bounds.

Of course just gut feeling, no proof.

@moorepants

moorepants commented Apr 13, 2026

Copy link
Copy Markdown
Member

Would a simpler demonstration of these variables bounds be something like bounds on the single applied force to different values throughout time? This would then surely have a global optima.

The change to this example would likely be a one line change then.

BTW, the thumbnail gif seems to be broken in the rendering.

@Peter230655

Peter230655 commented Apr 13, 2026

Copy link
Copy Markdown
Contributor Author
  1. You mean istead of -F_max < F(t) < F_max use a(t) < F(t) < b(t) , with a(t), b(t) prescribed?
    My guess is, that the solution would be to always go the the edges i.e. F(t) = a(t) or F(t) = b(t) (bang / bang solution), but surely I can try this.

  2. I definitely did not touch this thumbnail part. A problem is that I do not know how to see it until it is merged.

@moorepants

Copy link
Copy Markdown
Member

My guess is, that the solution would be to always go the the edges i.e. F(t) = a(t) or F(t) = b(t) (bang / bang solution), but surely I can try this.

The solution to this problem is a bang-bang if the torque is not minimized.

I definitely did not touch this thumbnail part. A problem is that I do not know how to see it until it is merged.

If you add or delete figures it will break the thumbnail. The rendered version is visible on every PR. I have the PR renderings set up on this repo.

@Peter230655

Peter230655 commented Apr 13, 2026

Copy link
Copy Markdown
Contributor Author

My guess is, that the solution would be to always go the the edges i.e. F(t) = a(t) or F(t) = b(t) (bang / bang solution), but surely I can try this.

The solution to this problem is a bang-bang if the torque is not minimized.

So, you think instead of minimizing the time to get the pendulum up I should minimize the torque, e.g.
$\int_0^{t_f} T(s)^2 ds$, with $t_f$ = (num_nodes-1) * h ?

I definitely did not touch this thumbnail part. A problem is that I do not know how to see it until it is merged.

If you add or delete figures it will break the thumbnail. The rendered version is visible on every PR. I have the PR renderings set up on this repo.

I must admit I did not look at this this time.
I am unaware of adding figures, but maybe printouts count as figures.

NB: I still do not really see why limiting variables should prevent a (local) minimum to be achieved.

@moorepants

Copy link
Copy Markdown
Member

I'll merge a change that shows the use of a variable bound, but this current rendition blows up the complexity of the example.

We should be able to make a one line change to an existing example to demonstrate how to provide an array as the bounds, e.g.:

diff --git a/examples-gallery/beginner/plot_pendulum_swing_up_variable_duration.py b/examples-gallery/beginner/plot_pendulum_swing_up_variable_duration.py
index b3d2d91..d5ddc7e 100644
--- a/examples-gallery/beginner/plot_pendulum_swing_up_variable_duration.py
+++ b/examples-gallery/beginner/plot_pendulum_swing_up_variable_duration.py
@@ -98,7 +98,11 @@ prob = Problem(obj, obj_grad, eom, state_symbols, num_nodes, h,
                known_parameter_map=par_map,
                instance_constraints=instance_constraints,
                time_symbol=t,
-               bounds={T(t): (-2.0, 2.0), h: (0.0, 0.5)},
+               bounds={T(t): (np.hstack((-3.0*np.ones(num_nodes//2 + 1),
+                                        -2.0*np.ones(num_nodes//2))),
+                              np.hstack((3.0*np.ones(num_nodes//2 + 1),
+                                         2.0*np.ones(num_nodes//2)))),
+                       h: (0.0, 0.5)},
                backend='numpy')
 
 # %%
@@ -118,7 +122,7 @@ print(info['obj_val'])
 
 # %%
 # Plot the optimal state and input trajectories.
-_ = prob.plot_trajectories(solution)
+_ = prob.plot_trajectories(solution, show_bounds=True)

gives:

image

That is all that is needed to demonstrate that you can supply an array or a constant.

@Peter230655

Copy link
Copy Markdown
Contributor Author

I'll merge a change that shows the use of a variable bound, but this current rendition blows up the complexity of the example.

I confess, I like to make them too complicated - I think, I alsways want to see what opty comes up with.
(But such things are probably better pushed to pst-notebooks)

We should be able to make a one line change to an existing example to demonstrate how to provide an array as the bounds, e.g.:

I will make such a simple change soon!

diff --git a/examples-gallery/beginner/plot_pendulum_swing_up_variable_duration.py b/examples-gallery/beginner/plot_pendulum_swing_up_variable_duration.py
index b3d2d91..d5ddc7e 100644
--- a/examples-gallery/beginner/plot_pendulum_swing_up_variable_duration.py
+++ b/examples-gallery/beginner/plot_pendulum_swing_up_variable_duration.py
@@ -98,7 +98,11 @@ prob = Problem(obj, obj_grad, eom, state_symbols, num_nodes, h,
                known_parameter_map=par_map,
                instance_constraints=instance_constraints,
                time_symbol=t,
-               bounds={T(t): (-2.0, 2.0), h: (0.0, 0.5)},
+               bounds={T(t): (np.hstack((-3.0*np.ones(num_nodes//2 + 1),
+                                        -2.0*np.ones(num_nodes//2))),
+                              np.hstack((3.0*np.ones(num_nodes//2 + 1),
+                                         2.0*np.ones(num_nodes//2)))),
+                       h: (0.0, 0.5)},
                backend='numpy')
 
 # %%
@@ -118,7 +122,7 @@ print(info['obj_val'])
 
 # %%
 # Plot the optimal state and input trajectories.
-_ = prob.plot_trajectories(solution)
+_ = prob.plot_trajectories(solution, show_bounds=True)

gives:

image That is all that is needed to demonstrate that you can supply an array or a constant.

@Peter230655 Peter230655 deleted the pendulum-with-bounds branch April 13, 2026 13:58
@Peter230655 Peter230655 restored the pendulum-with-bounds branch April 13, 2026 14:04
@Peter230655 Peter230655 reopened this Apr 13, 2026
@Peter230655

Copy link
Copy Markdown
Contributor Author

I am confused. I thought you added such a example yesterday, but now I see you changed something else on ``swing up variable duration''.

@moorepants

Copy link
Copy Markdown
Member

I have not added variable bounds to any example.

@Peter230655

Peter230655 commented Apr 14, 2026

Copy link
Copy Markdown
Contributor Author

I will do it - and very simple! :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants