utiasDSL / safe-control-gym

PyBullet CartPole and Quadrotor environments—with CasADi symbolic a priori dynamics—for learning-based control and RL
https://www.dynsyslab.org/safe-robot-learning/
MIT License
636 stars 132 forks source link

Replay Trained 3D drone in pybullet visualization #157

Closed zcase closed 2 months ago

zcase commented 3 months ago

How can we view the trained 3D models in the 3D pybullet sim environment?

adamhall commented 3 months ago

Hi @zcase,

I'm not entirely sure I understand your question. For any run, in the task config, if you include something like

task_config:
   ...
   gui: true
   ...

The GUI should appear with the robot and run the task. Are you asking to visualize the weights of some trained model or something like that?

zcase commented 3 months ago

@adamhall thanks for the reply. so I did add that and yes the pybullet environment visualized, but then quickly disappears.

I am trying to run the rl example that does the figure 8 with this command:

python rl_experiment.py --algo ppo --task quadrotor --overrides ./config_overrides/quadrotor_3D/quadrotor_3D_track.yaml ./config_overrides/quadrotor_3D/ppo_quadrotor_3D.yaml --kv_overrides algo_config.training=False

what happens is the pybullet env appears and then quickly disappears and then the plots show up. I am new to this repo so just trying to figure out how everything works with the RL stuff. I want to see the movement of the drone in the simulation is essentially what I am looking for.

adamhall commented 3 months ago

Hey @zcase,

I took a look at the problem. There are a couple things going on (some of which might be a bug).

  1. By not including the flag task_config.randomized_init=False, as seen here, it seems like the system is able to initialize outside of the constraint boundary (at least for me), which causes the simulation to terminate instantly. @Federico-PizarroBejarano is this a bug? The randomized init should remain in the constraint boundaries right?
  2. In rl_experiment.py, is seems like we are overriding the GUI argument to False, ignoring anything put in the yaml. If you change this line to env = env_func(gui=True), and then run rl_experiment.sh, you'll see the quadrotor run in the pybullet environment.

Let me know if this works for you.

zcase commented 3 months ago

@adamhall

1) Yea mine seems to terminate early as well which didn't seem like normal behavior. 2) I did overwrite/add in the gui=True and that popped up the pybullet environment, but then it immediately closes which is probably related to the first issue you mentioned.

adamhall commented 3 months ago

Did it work when you tried it with the task_config.randomized_init=False? If runs fine for me when I include this flag.

zcase commented 3 months ago

@adamhall Does this mean its working:

pybullet build time: Aug 15 2024 16:42:46
CasADi - 2024-08-23 12:09:31 WARNING("The options 't0', 'tf', 'grid' and 'output_t0' have been deprecated.
The same functionality is provided by providing additional input arguments to the 'integrator' function, in particular:
 * Call integrator(..., t0, tf, options) for a single output time, or
 * Call integrator(..., t0, grid, options) for multiple grid points.
The legacy 'output_t0' option can be emulated by including or excluding 't0' in 'grid'.
Backwards compatibility is provided in this release only.") [.../casadi/core/integrator.cpp:515]
starting thread 0
started testThreads thread 0 with threadHandle 0000000000000480
argc=2
argv[0] = --unused
argv[1] = --start_demo_name=Physics Server
ExampleBrowserThreadFunc started
Version = 4.6.0 - Build 31.0.101.5186
Vendor = Intel
Renderer = Intel(R) Iris(R) Xe Graphics
b3Printf: Selected demo: Physics Server
starting thread 0
started MotionThreads thread 0 with threadHandle 00000000000006FC
MotionThreadFunc thread started
average_length: 1.000
length: 1.000
average_return: 0.000
average_rmse: 3.204
rmse: 3.204
rmse_std: 0.000
worst_case_rmse_at_0.5: 3.204
failure_rate: 1.000
average_constraint_violation: 1.000
constraint_violation_std: 0.000
constraint_violation: 1.000
Evaluation done.
numActiveThreads = 0
stopping threads
Thread with taskId 0 with handle 00000000000006FC exiting
Thread TERMINATED
finished
numActiveThreads = 0
btShutDownExampleBrowser stopping threads
Thread with taskId 0 with handle 0000000000000480 exiting
Thread TERMINATED

If so then yes it is but the gui just flashes on and then off and I don't really get to visually see it run the task. Is there another config or can you send a video of what it looks like when you run? Mine runs but it is really a flash.

zcase commented 3 months ago

@adamhall I was able to get it working. The issue I had was that i assumed the confings handled the arguments into the run function:

def run(gui=False, plot=True, n_episodes=1, n_steps=None, curr_path='.'):

They still probably do, but just weren't in the configs. When I changed the n_episodes from 1 to 1000 I was able to see it move to the target.

Thank you for your help and patience as I start looking into this project/repo!

adamhall commented 2 months ago

Oh great! Glad you managed to get it working :) If you have any more issues let us know.