#10 Feature/launch files xml - #11
Conversation
|
The joypad gait switching was implemented by me here: if you cherry pick the same mods on the ROS2 branch of our ocs2 fork, it should work. You can test it with a virtual joypad like this one: https://discourse.openrobotics.org/t/ros-2-rqt-virtual-joystick-smooth-robot-control-without-hardware/50582 When that's done and tested, I think we can merge and leave the testing on the hardware for a later PR |
mcamurri
left a comment
There was a problem hiding this comment.
Generally good we need a little adjustments, check my previous comment also.
| controller_manager: | ||
| ros__parameters: | ||
| update_rate: 100 # Hz | ||
| update_rate: 100 |
There was a problem hiding this comment.
Leave the comment so people know it's hertz
There was a problem hiding this comment.
updated joy.yaml to make it compatible with ros2
There was a problem hiding this comment.
Since we are making new files, I would enforce the two spaces rule for indentation, thanks.
|
|
||
| <let name="legged_robot_description" value="$(command 'xacro $(find-pkg-share legged_unitree_description)/urdf/robot.xacro robot_type:=$(var robot_type)')"/> | ||
|
|
||
| <node pkg="legged_common" exec="generate_urdf.sh" output="screen" name="generate_urdf" |
There was a problem hiding this comment.
What's the purpose of the generate_urdf.sh script? It looks like it's doing the same as the command in line 4.
Check what does generate_urdf.sh is actually doing, was done in the original code and why, and whether it is still necessary.
My best guess is that it needs the urdf to load into the robot state publisher, but also needs a physical file to load it into pinocchio at runtime. But there's the risk the two descriptions are not exactly identical.
Ideally, either the content of the file should be dumped into the parameter, or viceversa.
In the future we will get rid of this anyway and make specific launch files for specific robots using the official URDF definition.
There was a problem hiding this comment.
<let name="legged_robot_description" value="$(command 'xacro ...')"/>
runs xacro once and holds the result in memory, for
robot_state_publisher's robot_description parameter.
generate_urdf.sh runs the same xacro file/args again and writes the
result to a file, /tmp/legged_control/<robot_type>.urdf, because
LeggedInterface → Pinocchio (legged_interface/src/LeggedInterface.cpp,
createPinocchioInterface) needs an actual filesystem path. It can't take
the URDF as an in-memory string. That file is read later via the urdfFile
param in legged_controllers/launch/load_controller_launch.xml:.
So they're not redundant. They serve two different consumers that want the
URDF in two different shapes (string vs. path). This pattern already existed
in the ROS1 launch files and predates the ROS2 port.
The two descriptions were not unified and that risk is real but
untouched for now. Both invocations use identical inputs today, so the
output text matches, but they're still two independent xacro runs with no
cross-check: if someone adds an argument to one and not the other, the TF
description and the dynamics-model URDF would silently diverge.
What was actually broken, and what got fixed: in
legged_unitree_hw_launch.xml specifically, line 4's legged_robot_description
was computed but never consumed. No node in the real-hardware launch chain
used it, so the file was necessary but the in-memory string was pure dead
computation. Added a robot_state_publisher node consuming it, mirroring
empty_world_launch.xml. Now both forms of the URDF are actually used again.
Co-authored-by: AlexBarbi <alejandro.enrique.barbi@gmai.com>


Summary
Ports the legacy ROS 1-style
.launchfiles inlegged_controllers,legged_unitree_descriptionandlegged_unitree_hwto native ROS 2 XML launch format (*_launch.xml). Also confirmed that both theocs2_legged_robot_rosdemo and thelegged_controllerscontroller loading work end-to-end with these new launch files — see attached videos.Demos
ocs2_legged_robot_rosdemoLeggedRobot_example.mp4
Shows the keyboard-driven gait command (
legged_robot_gait_command) working againstocs2_legged_robot_ros, confirming the demo still works after the launch file port.legged_controllersdemoLeggedControl.mp4
Shows Gazebo (gz) starting from
empty_world_launch.xmland the controllers loading successfully fromload_controller_launch.xml.Changes
legged_unitree_description:empty_world.launch→empty_world_launch.xmlBeyond the mechanical ROS 1 → ROS 2 syntax translation (
$(find ...)→$(find-pkg-share ...),doc→description,param→let,type→exec, etc.), three things changed because Gazebo Classic +gazebo_rosdon't exist in this ROS 2 setup:robot_state_publishernode. In ROS 1,gazebo_ros/spawn_modelimplicitly took care of publishing the robot's TF tree. In ROS 2 that's no longer implicit, sorobot_state_publisheris now launched explicitly withlegged_robot_descriptionas itsrobot_descriptionparam.gazebo_rosforros_gz_sim.empty_world.launch'sgazebo_ros/empty_world.launchinclude andspawn_modelnode are replaced withros_gz_sim'sgz_sim.launch.py(loadsempty_world.world) and theros_gz_sim createnode (spawns the robot from therobot_descriptiontopic).ros_gz_bridge parameter_bridgenode for/clock. Gazebo (gz) publishes sim time on its own message type; without bridging/clock(gz.msgs.Clock→rosgraph_msgs/msg/Clock),use_sim_timenever gets a clock and ROS 2 nodes stall on sim time.legged_controllers:load_controller.launch→load_controller_launch.xmlcontroller_manager/spawnercall loading["controllers/joint_state_controller", "controllers/legged_controller", "controllers/imu_sensor_controller"]→ three separatecontroller_manager/spawnernodes, one per controller.controllers/joint_state_controller→joint_state_broadcastercontrollers/imu_sensor_controller→imu_sensor_broadcastercontrollers/legged_controller→legged_controllercontrollers.yamlupdated to match: dropped the standalonejoint_state_broadcasterandlegged_controllerparameter blocks and params that don't apply to ros2_control broadcasters (map_interface_to_joint_state,use_local_topics,use_urdf_to_filter,publish_rate), keeping only whatimu_sensor_broadcasterneeds (sensor_name,frame_id).joy_teleop.launch.py→joy_teleop_launch.xmlfor consistency with the rest of the package.legged_unitree_hwSame
.launch.py→*_launch.xmlconversion fora1,aliengo,go1and the top-levellegged_unitree_hw.launch.py. Not tested on real hardware — README updated to flag this.Known limitation: joypad gait switching doesn't work
The
joy:=truepath (legged_robot_gait_joy_command) is not functional —ocs2_legged_robot_rosdoesn't ship a ROS 2 package/executable for the joypad-based gait command, so there's nothing for that node to run. The default keyboard-based gait command (legged_robot_gait_command,joy:=false) is unaffected and is what's used in theocs2_legged_robot_rosdemo above.Testing
ros2 launch legged_unitree_description empty_world_launch.xml— Gazebo (gz) starts, robot spawns, TF is published,/clockis bridged correctly.ros2 launch legged_controllers load_controller_launch.xml— all three controllers load successfully (video attached).ocs2_legged_robot_roskeyboard gait demo — confirmed working (video attached).joy:=true) — known not to work, see above.legged_unitree_hwlaunch files — not tested on physical hardware.Tested on WSL2 -> Ubuntu-24.04