-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
One-legged Cycling Time Trial Example #164
Conversation
Closer: one-legged-time-trial-third-solution.mp4 |
…nts, adjusted plots.
… inputs parameters.
Leaving it at this stage: one-legged-time-trial-sixth-solution.mp4There is still something weird that causes the crank speed to jump. Maybe it is a weird config of the muscle. Not sure. I could try solving with only joint torques to see if it exposes something else. But overall good progress. I'll come back to it later in the week. |
There is some jiggle, but that may because I cut the solve for the long distance before optimal was found. |
It did find a solution the first time but the second time running it plateaued and ran into max iteration count |
One thing to do would be to give a much better initial guess. For example we could give alternating square waves for the four muscles that have the likely period of the crank cycle. Right now you can see that I have a |
Feel free to try to fix that by making a square wave guess for the muscle excitations. |
You can also find the |
We could make an oval chain ring with three parameters: angle relative to crank, ellipse width/height to find the optimal oval chain ring or something similar. But we can first see if a crank length and/or seat post height as a free parameter will solve. |
@Neville-N can you see if you can run this on google colab? |
I will start looking at it this afternoon |
I tried solving with the seat height also added as a free optmization variable and it found a solution (87cm for the leg setup in fb9cf4c). Results: first-optimal-seat-height-solution-87cm.mp4 |
diff for making seat height free (not committing): diff --git a/examples-gallery/plot_one_legged_time_trial.py b/examples-gallery/plot_one_legged_time_trial.py
index 4e37339..5210be4 100644
--- a/examples-gallery/plot_one_legged_time_trial.py
+++ b/examples-gallery/plot_one_legged_time_trial.py
@@ -534,7 +534,7 @@ q_0 = np.array([q1_0, q2_0, q3_0, q4_0])
# Crank revolutions are proportional to distance traveled so the race distance
# is defined by number of crank revolutions.
crank_revs = 4
-samples_per_rev = 40
+samples_per_rev = 120
num_nodes = crank_revs*samples_per_rev + 1
h = sm.symbols('h', real=True)
@@ -574,8 +574,11 @@ bounds = {
knee_bot_mus.e: (0.0, 1.0),
knee_top_mus.e: (0.0, 1.0),
h: (0.0, 0.1),
+ ls: (0.6, 1.2),
}
+del par_map[ls]
+
# %
# Instantiate the Optimal Control Problem
# =======================================
@@ -591,7 +594,7 @@ problem = Problem(
bounds=bounds,
)
problem.add_option('nlp_scaling_method', 'gradient-based')
-problem.add_option('max_iter', 1000)
+problem.add_option('max_iter', 4000)
initial_guess = np.random.random(problem.num_free)
@@ -608,6 +611,7 @@ initial_guess[1*num_nodes:2*num_nodes] = q2_guess
initial_guess[4*num_nodes:5*num_nodes] = u1_guess
initial_guess[5*num_nodes:6*num_nodes] = u2_guess
initial_guess[-4*num_nodes - 1:] = 0.5 # e
+initial_guess[-2] = 0.8
initial_guess[-1] = 0.01
problem.plot_trajectories(initial_guess)
@@ -616,9 +620,12 @@ problem.plot_trajectories(initial_guess)
solution, info = problem.solve(initial_guess)
xs, us, ps, h_val= parse_free(solution, len(state_vars), 4, num_nodes,
variable_duration=True)
-print('Optimal value h:', solution[-1])
+print('Optimal value h:', h_val)
+print('Optimal value ls:', ps)
print(info['status_msg'])
+p_vals[14] = ps[0]
+
# %%
problem.plot_objective_value() |
… comment configs.
This is mergable as a working example that is complete. I will iterate on details in future PRs. |
Setup
I'm using this conda env
opty-sympy-dev-env.yml
:after activating I install dev versions of sympy and opty, for example this can work:
or clone them and do an editable install.
TODO
Solve with only joint torquesCheck to see if opty actually generates the instance constraints correctlyCurrent system sketch:
![image](https://private-user-images.githubusercontent.com/276007/339025716-6916b6f3-9b3e-4bb7-a277-10e4670fe113.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk2OTYwNTYsIm5iZiI6MTczOTY5NTc1NiwicGF0aCI6Ii8yNzYwMDcvMzM5MDI1NzE2LTY5MTZiNmYzLTliM2UtNGJiNy1hMjc3LTEwZTQ2NzBmZTExMy5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjE2JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxNlQwODQ5MTZaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1hNDkxMzZjNjgyY2ExYzE1YzE1M2NmZGMyZmM2ZDZhZDFiOWY2YTE3NDdlMjc0Y2E2ZjBhOWY4YWM2NDRmMjc0JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.eshSgdOpc78YNuF2buB7fsVFGLDXbfWLkTz_jcKNR7Y)