diff --git a/descriptions/README.md b/descriptions/README.md index 5c75137..ed0e009 100644 --- a/descriptions/README.md +++ b/descriptions/README.md @@ -1,21 +1,22 @@ # Robot Descriptions -This folder contains the URDF and SRDF files for the quadruped robot. +This folder contains the URDF and SRDF files for the quadruped robot. * Unitree - * [Go1](unitree/go1_description/) - * [Go2](unitree/go2_description/) - * [A1](unitree/a1_description/) - * [Aliengo](unitree/aliengo_description/) - * [B2](unitree/b2_description/) + * [Go1](unitree/go1_description/) + * [Go2](unitree/go2_description/) + * [A1](unitree/a1_description/) + * [Aliengo](unitree/aliengo_description/) + * [B2](unitree/b2_description/) * Xiaomi - * [Cyberdog](xiaomi/cyberdog_description/) - + * [Cyberdog](xiaomi/cyberdog_description/) ## Steps to transfer urdf to Mujoco model + * Install [Mujoco](https://github.com/google-deepmind/mujoco) * Transfer the mesh files to mujoco supported format, like stl. -* Adjust the urdf tile to match the mesh file. Transfer the mesh file from .dae to .stl may change the scale size of the mesh file. +* Adjust the urdf tile to match the mesh file. Transfer the mesh file from .dae to .stl may change the scale size of the + mesh file. * use `xacro` to generate the urdf file. ``` xacro robot.xacro > ../urdf/robot.urdf @@ -23,4 +24,20 @@ This folder contains the URDF and SRDF files for the quadruped robot. * use mujoco to convert the urdf file to mujoco model. ``` compile robot.urdf robot.xml - ``` \ No newline at end of file + ``` + +## Dependencies for Gazebo Simulation +Gazebo Simulation only tested on ROS2 Jazzy. I didn't add support for ROS2 Humble because the package name is different. +* Gazebo Harmonic + ```bash + sudo apt-get install ros-jazzy-ros-gz + ``` +* Ros2-Control for Gazebo + ```bash + sudo apt-get install ros-jazzy-gz-ros2-control + ``` +* Legged PD Controller + ```bash + cd ~/ros2_ws + colcon build --packages-up-to leg_pd_controller + ``` \ No newline at end of file diff --git a/descriptions/unitree/a1_description/xacro/leg.xacro b/descriptions/unitree/a1_description/xacro/leg.xacro index f447107..ac6fa93 100644 --- a/descriptions/unitree/a1_description/xacro/leg.xacro +++ b/descriptions/unitree/a1_description/xacro/leg.xacro @@ -2,225 +2,229 @@ - + - + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - 0.2 - 0.2 - - - .5 .5 .5 1.0 - .5 .5 .5 1.0 - .5 .5 .5 1.0 - - - - - 0.2 - 0.2 - 0 - - - .175 .175 .175 1.0 - .175 .175 .175 1.0 - .175 .175 .175 1.0 - - - - - + + 0.2 + 0.2 + + + .5 .5 .5 1.0 + .5 .5 .5 1.0 + .5 .5 .5 1.0 + + + + + 0.2 + 0.2 + 0 + + + .175 .175 .175 1.0 + .175 .175 .175 1.0 + .175 .175 .175 1.0 + + + + + - - 0.6 - 0.6 - 1 - - - .5 .5 .5 1.0 - .5 .5 .5 1.0 - .5 .5 .5 1.0 - - - + + 0.6 + 0.6 + 1 + + + .5 .5 .5 1.0 + .5 .5 .5 1.0 + .5 .5 .5 1.0 + + + - - 0.6 - 0.6 - 1 - - - .175 .175 .175 1.0 - .175 .175 .175 1.0 - .175 .175 .175 1.0 - - - - - + + 0.6 + 0.6 + 1 + + + .175 .175 .175 1.0 + .175 .175 .175 1.0 + .175 .175 .175 1.0 + + + + + - - + + diff --git a/descriptions/unitree/go2_description/README.md b/descriptions/unitree/go2_description/README.md index 10e2bb3..d333f85 100644 --- a/descriptions/unitree/go2_description/README.md +++ b/descriptions/unitree/go2_description/README.md @@ -12,7 +12,7 @@ Tested environment: ## Build ```bash cd ~/ros2_ws -colcon build --packages-up-to go2_description +colcon build --packages-up-to go2_description --symlink-install ``` ## Visualize the robot @@ -23,6 +23,7 @@ ros2 launch go2_description visualize.launch.py ``` ## Launch ROS2 Control +### Mujoco Simulator * Unitree Guide Controller ```bash source ~/ros2_ws/install/setup.bash @@ -33,6 +34,13 @@ ros2 launch go2_description visualize.launch.py source ~/ros2_ws/install/setup.bash ros2 launch go2_description ocs2_control.launch.py ``` + +### Gazebo Simulator +* Unitree Guide Controller + ```bash + source ~/ros2_ws/install/setup.bash + ros2 launch go2_description gazebo_unitree_guide.launch.py + ``` ## When used for isaac gym or other similiar engine diff --git a/descriptions/unitree/go2_description/config/gazebo.yaml b/descriptions/unitree/go2_description/config/gazebo.yaml new file mode 100644 index 0000000..ea18712 --- /dev/null +++ b/descriptions/unitree/go2_description/config/gazebo.yaml @@ -0,0 +1,142 @@ +# Controller Manager configuration +controller_manager: + ros__parameters: + update_rate: 2000 # Hz + + # Define the available controllers + joint_state_broadcaster: + type: joint_state_broadcaster/JointStateBroadcaster + + imu_sensor_broadcaster: + type: imu_sensor_broadcaster/IMUSensorBroadcaster + + leg_pd_controller: + type: leg_pd_controller/LegPdController + + unitree_guide_controller: + type: unitree_guide_controller/UnitreeGuideController + + legged_gym_controller: + type: legged_gym_controller/LeggedGymController + +imu_sensor_broadcaster: + ros__parameters: + sensor_name: "imu_sensor" + frame_id: "imu_link" + +leg_pd_controller: + ros__parameters: + joints: + - FR_hip_joint + - FR_thigh_joint + - FR_calf_joint + - FL_hip_joint + - FL_thigh_joint + - FL_calf_joint + - RR_hip_joint + - RR_thigh_joint + - RR_calf_joint + - RL_hip_joint + - RL_thigh_joint + - RL_calf_joint + + command_interfaces: + - effort + + state_interfaces: + - position + - velocity + +unitree_guide_controller: + ros__parameters: + command_prefix: "leg_pd_controller" + joints: + - FR_hip_joint + - FR_thigh_joint + - FR_calf_joint + - FL_hip_joint + - FL_thigh_joint + - FL_calf_joint + - RR_hip_joint + - RR_thigh_joint + - RR_calf_joint + - RL_hip_joint + - RL_thigh_joint + - RL_calf_joint + + command_interfaces: + - effort + - position + - velocity + - kp + - kd + + state_interfaces: + - effort + - position + - velocity + + feet_names: + - FR_foot + - FL_foot + - RR_foot + - RL_foot + + imu_name: "imu_sensor" + base_name: "base" + + imu_interfaces: + - orientation.w + - orientation.x + - orientation.y + - orientation.z + - angular_velocity.x + - angular_velocity.y + - angular_velocity.z + - linear_acceleration.x + - linear_acceleration.y + - linear_acceleration.z + +legged_gym_controller: + ros__parameters: + update_rate: 200 # Hz + config_folder: "/home/tlab-uav/ros2_ws/install/a1_description/share/a1_description/config/issacgym" + command_prefix: "leg_pd_controller" + joints: + - FL_hip_joint + - FL_thigh_joint + - FL_calf_joint + - FR_hip_joint + - FR_thigh_joint + - FR_calf_joint + - RL_hip_joint + - RL_thigh_joint + - RL_calf_joint + - RR_hip_joint + - RR_thigh_joint + - RR_calf_joint + + command_interfaces: + - effort + - position + - velocity + - kp + - kd + + state_interfaces: + - effort + - position + - velocity + + imu_name: "imu_sensor" + imu_interfaces: + - orientation.w + - orientation.x + - orientation.y + - orientation.z + - angular_velocity.x + - angular_velocity.y + - angular_velocity.z + - linear_acceleration.x + - linear_acceleration.y + - linear_acceleration.z \ No newline at end of file diff --git a/descriptions/unitree/go2_description/launch/gazebo_unitree_guide.launch.py b/descriptions/unitree/go2_description/launch/gazebo_unitree_guide.launch.py new file mode 100644 index 0000000..10f6308 --- /dev/null +++ b/descriptions/unitree/go2_description/launch/gazebo_unitree_guide.launch.py @@ -0,0 +1,106 @@ +import os + +import xacro +from ament_index_python.packages import get_package_share_directory +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument, OpaqueFunction, IncludeLaunchDescription, RegisterEventHandler +from launch.launch_description_sources import PythonLaunchDescriptionSource +from launch.event_handlers import OnProcessExit +from launch.substitutions import PathJoinSubstitution +from launch_ros.actions import Node +from launch_ros.substitutions import FindPackageShare + +package_description = "go2_description" + + +def process_xacro(): + pkg_path = os.path.join(get_package_share_directory(package_description)) + xacro_file = os.path.join(pkg_path, 'xacro', 'robot.xacro') + robot_description_config = xacro.process_file(xacro_file, mappings={'GAZEBO': 'true'}) + return robot_description_config.toxml() + + +def generate_launch_description(): + rviz_config_file = os.path.join(get_package_share_directory(package_description), "config", "visualize_urdf.rviz") + + robot_description = process_xacro() + + gz_spawn_entity = Node( + package='ros_gz_sim', + executable='create', + output='screen', + arguments=['-topic', 'robot_description', '-name', + 'go2', '-allow_renaming', 'true', '-z', '0.5'], + ) + + robot_state_publisher = Node( + package='robot_state_publisher', + executable='robot_state_publisher', + name='robot_state_publisher', + parameters=[ + { + 'publish_frequency': 20.0, + 'use_tf_static': True, + 'robot_description': robot_description, + 'ignore_timestamp': True + } + ], + ) + + joint_state_publisher = Node( + package="controller_manager", + executable="spawner", + arguments=["joint_state_broadcaster", + "--controller-manager", "/controller_manager"], + ) + + imu_sensor_broadcaster = Node( + package="controller_manager", + executable="spawner", + arguments=["imu_sensor_broadcaster", + "--controller-manager", "/controller_manager"], + ) + + leg_pd_controller = Node( + package="controller_manager", + executable="spawner", + arguments=["leg_pd_controller", + "--controller-manager", "/controller_manager"], + ) + + unitree_guide_controller = Node( + package="controller_manager", + executable="spawner", + arguments=["unitree_guide_controller", "--controller-manager", "/controller_manager"], + ) + + return LaunchDescription([ + Node( + package='rviz2', + executable='rviz2', + name='rviz_ocs2', + output='screen', + arguments=["-d", rviz_config_file] + ), + Node( + package='ros_gz_bridge', + executable='parameter_bridge', + arguments=['/clock@rosgraph_msgs/msg/Clock[gz.msgs.Clock'], + output='screen' + ), + IncludeLaunchDescription( + PythonLaunchDescriptionSource( + [PathJoinSubstitution([FindPackageShare('ros_gz_sim'), + 'launch', + 'gz_sim.launch.py'])]), + launch_arguments=[('gz_args', [' -r -v 4 empty.sdf'])]), + robot_state_publisher, + gz_spawn_entity, + leg_pd_controller, + RegisterEventHandler( + event_handler=OnProcessExit( + target_action=leg_pd_controller, + on_exit=[imu_sensor_broadcaster, joint_state_publisher, unitree_guide_controller], + ) + ), + ]) diff --git a/descriptions/unitree/go2_description/xacro/gazebo.xacro b/descriptions/unitree/go2_description/xacro/gazebo.xacro index f449f44..1b1fb45 100644 --- a/descriptions/unitree/go2_description/xacro/gazebo.xacro +++ b/descriptions/unitree/go2_description/xacro/gazebo.xacro @@ -1,257 +1,188 @@ - - - - - /go2_gazebo - gazebo_ros_control/DefaultRobotHWSim - - + - - + + + gz_ros2_control/GazeboSimSystem + - - - - 100 - - FL_foot - 0 0 0 0 0 0 - - - + + + + + + - - - trunk - /apply_force/trunk - - + + + + + + - - true - - true - 1000 - true - __default_topic__ - - trunk_imu - imu_link - 1000.0 - 0.0 - 0 0 0 - 0 0 0 - imu_link - - 0 0 0 0 0 0 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - 100 - - - FR_calf_fixed_joint_lump__FR_foot_collision_1 - - - - - - 100 - - - FL_calf_fixed_joint_lump__FL_foot_collision_1 - - - - - - 100 - - - RR_calf_fixed_joint_lump__RR_foot_collision_1 - - - - - - 100 - - - RL_calf_fixed_joint_lump__RL_foot_collision_1 - - - + + + + + + - - - - - FR_foot_contact - - - - - - - FL_foot_contact - - - - - - - RR_foot_contact - - - - - - - RL_foot_contact - - - + + + + + + - - false - + + + + + + - - 0.2 - 0.2 - - - + + + + + + + + + + + + + - - 0.2 - 0.2 - + + + $(find a1_description)/config/gazebo.yaml + + + + - - 0.2 - 0.2 - + + 0.6 + 0.6 + 1 + - - - 0.2 - 0.2 - - - - 0.2 - 0.2 - 1 - - - - - 0.2 - 0.2 - 1 - - - 0.6 - 0.6 - 1 - - - - - - - 0.2 - 0.2 - - - 0.2 - 0.2 - 1 - - - - - 0.2 - 0.2 - 1 - - - 0.6 - 0.6 - 1 - - - - - - - 0.2 - 0.2 - - - 0.2 - 0.2 - 1 - - - - - 0.2 - 0.2 - 1 - - - 0.6 - 0.6 - 1 - - - - - - - 0.2 - 0.2 - - - 0.2 - 0.2 - 1 - - - - - 0.2 - 0.2 - 1 - - - 0.6 - 0.6 - 1 - - - + + + 1 + 500 + true + imu + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + diff --git a/descriptions/unitree/go2_description/xacro/leg.xacro b/descriptions/unitree/go2_description/xacro/leg.xacro index 4b78614..5c8f406 100755 --- a/descriptions/unitree/go2_description/xacro/leg.xacro +++ b/descriptions/unitree/go2_description/xacro/leg.xacro @@ -2,175 +2,202 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - 0 - - - - + 0 + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - + + 0.2 + 0.2 + + + + 0.2 + 0.2 + 0 + + + + + + 0.6 + 0.6 + 1 + + + + 0.6 + 0.6 + 1 + + + + + + diff --git a/descriptions/unitree/go2_description/xacro/robot.xacro b/descriptions/unitree/go2_description/xacro/robot.xacro index 56c9079..6ad195d 100755 --- a/descriptions/unitree/go2_description/xacro/robot.xacro +++ b/descriptions/unitree/go2_description/xacro/robot.xacro @@ -3,11 +3,19 @@ + - + + + + + + + +