ros2_sim is a learning- and research-oriented robot arm simulator focused on high-frequency control, analytical dynamics, and deterministic software‑in‑the‑loop (SIL) testing. It targets kHz‑class control loops by leveraging Pinocchio for fast and accurate rigid‑body dynamics instead of heavy contact‑rich physics engines.
This is not a general-purpose physics engine or a Gazebo replacement. The intent is to teach and enable reliable controller development with a clear, inspectable dynamics pipeline.
ros2_sim prioritizes:
- High‑frequency control loops (kHz‑range)
- Analytical dynamics (mass matrices, Jacobians, Coriolis terms)
- Deterministic stepping for reproducible SIL testing
- Learning value: dynamics are visible, hackable, and debuggable
It does not aim for maximum contact realism, photorealism, or full soft-body physics. Those are intentionally out-of-scope to preserve stability and performance for controller development.
Ensure you have the following installed on your system:
- Docker
- Visual Studio Code with Remote - Containers extension
-
Clone this repository into your desired workspace directory (e.g.,
~/workspace):git clone https://github.com/PetoAdam/ros2_sim.git
-
Open the repository in Visual Studio Code:
code . -
When prompted, reopen the repository in the devcontainer. If not prompted, you can manually reopen it by pressing
F1and selectingRemote-Containers: Reopen in Container.
Once inside the devcontainer, first build the ros2_sim_msgs package:
cd /home/ws
colcon build --packages-select ros2_sim_msgsSource the workspace
source install/setup.bashAnd then build all the packages:
colcon buildThere are preset launch configurations that can be easily run without having to open multiple terminals for every package. Current presets:
-
launch_all_with_rviz.launch.py: This launch file runs the simulation, the PID controller, ros2_control, MoveIt, and the RViz Visualization (with Motion Planning enabled).
- To run it, make sure to build and source the workspace and then run:
ros2 launch /home/ws/launch_all_with_rviz.launch.py
-
launch_all_with_rviz_custom_planner.launch.py: This launch file runs the simulation, the PID controller, ros2_control, the motion planner, and the RViz Visualization packages with their correct launch files.
- To run it, make sure to build and source the workspace and then run:
ros2 launch /home/ws/launch_all_with_rviz_custom_planner.launch.py
- To test it, run this command from another sourced terminal:
ros2 action send_goal /plan_and_execute ros2_sim_msgs/action/PlanAndExecute "{target_type: 0, target_pose: {position: {x: 0.4, y: 0.0, z: 0.3}, orientation: {x: 1.0, y: 1.0, z: 1.0, w: 1.0}}, planning_pipeline: 'pilz_industrial_motion_planner', planner_id: 'PTP', timeout: 10.0, max_velocity_scaling_factor: 0.2, max_acceleration_scaling_factor: 0.1}" -
launch_all_with_custom_planner.launch.py: This launch file runs the simulation, the PID controller, ros2_control, the motion planner, and the gateway packages with their correct launch files.
- To run it, make sure to build and source the workspace and then run:
ros2 launch /home/ws/launch_all_with_custom_planner.launch.py
- To test it, run this command from another sourced terminal:
ros2 action send_goal /plan_and_execute ros2_sim_msgs/action/PlanAndExecute "{target_type: 0, target_pose: {position: {x: 0.4, y: 0.0, z: 0.3}, orientation: {x: 1.0, y: 1.0, z: 1.0, w: 1.0}}, planning_pipeline: 'pilz_industrial_motion_planner', planner_id: 'PTP', timeout: 10.0, max_velocity_scaling_factor: 0.2, max_acceleration_scaling_factor: 0.1}"
To start the simulation, use the following command inside the devcontainer after making sure the workspace was built and sourced:
ros2 launch src/ros2_sim_simulation/launch/simulation.launch.pyRViz2 can used to render the robot inside the simulation. To launch rendering, use the following command inside the devcontainer after making sure the simulation package is running and the workspace was built and sourced:
ros2 launch src/ros2_sim_ur3_description/launch/simulation.launch.pyIf you also wish to use the motion planning functionality launch:
ros2 launch src/ros2_sim_ur3_description/launch/planner.launch.pyThe web UI now lives in a dedicated repository:
https://github.com/PetoAdam/ros2_sim_ui
It remains an optional companion for ros2_sim, providing a lightweight, modern web-based renderer that connects to the gateway via WebSocket. See the UI repository for installation and usage details.
For a more formal overview of the dynamics, control framing, and simulation assumptions, see docs/ACADEMIC.md.
The PID controller package is responsible for turning desired joint positions into torque values for the joints.
ros2 launch src/ros2_sim_pid_controller/launch/pid_controller.launch.pyThe PID controller can be tested via the terminal using:
ros2 topic pub /desired_positions sensor_msgs/msg/JointState "{header: {stamp: {sec: 0, nanosec: 0}}, name: [shoulder_pan_joint', 'shoulder_lift_joint', 'elbow_joint', 'wrist_1_joint', 'wrist_2_joint', 'wrist_3_joint'], position: [0.2, 0.2, 0.0, 0.0, 0.0, 0.0]}"This command sends the joints to [0.2, 0.2, 0.0, 0.0, 0.0, 0.0].
You can run an automated tuner node that sweeps gain multipliers, resets the simulation between trials, and logs detailed progress:
ros2 launch ros2_sim_pid_tuner pid_tuner.launch.pyTune parameters in:
src/ros2_sim_pid_tuner/config/pid_tuner.yamlModes:
- global: scales all joints together
- per_joint: tunes each joint independently
- combined: global pass, then per-joint refinement
The project also comes with its own ros2_control integration, which converts trajectory data to joint positions, which are sent towards the PID controller.
ros2 launch src/ros2_sim_control/bringup/launch/ros2_sim_control.launch.py It can be tested via supplying it this demo trajectory:
ros2 topic pub /robot_arm_controller/joint_trajectory trajectory_msgs/msg/JointTrajectory "{header: {stamp: {sec: 0, nanosec: 0}, frame_id: base_link}, joint_names: ['shoulder_pan_joint', 'shoulder_lift_joint', 'elbow_joint', 'wrist_1_joint', 'wrist_2_joint', 'wrist_3_joint'], points: [{positions: [0, 0, 0, 0, 0, 0], velocities: [], accelerations: [], effort: [], time_from_start: {sec: 0, nanosec: 0}}, {positions: [0.8, 0.8, 0, 0, 0, 0], velocities: [], accelerations: [], effort: [], time_from_start: {sec: 3, nanosec: 0}}, {positions: [0, 0, 0, 0, 0, 0], velocities: [], accelerations: [], effort: [], time_from_start: {sec: 6, nanosec: 0}}]}" --onceThis project utilizes MoveIt2 for motion planning. To enable motion planning and execute planned trajectories, follow these steps:
The motion planner UI for the default MoveIt integration runs in RViz, so make sure to run the visualization package that has motion planning included.
To launch the motion planner, run:
ros2 launch ros2_sim_moveit_config move_group.launch.pyPlanning and executing trajectories can be done via the MotionPlanning window inside RViz:

The custom motion planner library in this repository enhances the functionality of motion planning for the robot simulation. It integrates with MoveIt2 and provides additional capabilities tailored to specific scenarios. It uses a custom ros2 action to listen for advanced motion requests.
To launch the custom motion planner, make sure the default moveit_config motion planner library is not running and run:
ros2 launch ros2_sim_motion_planner motion_planner.launch.pyThe library can be tested with the following commands:
Cartesian:
ros2 action send_goal /plan_and_execute ros2_sim_msgs/action/PlanAndExecute "{target_type: 0, target_pose: {position: {x: 0.4, y: 0.0, z: 0.3}, orientation: {x: 1.0, y: 1.0, z: 1.0, w: 1.0}}, planning_pipeline: 'pilz_industrial_motion_planner', planner_id: 'PTP', timeout: 10.0, max_velocity_scaling_factor: 0.2, max_acceleration_scaling_factor: 0.1}"Joint Space:
ros2 action send_goal /plan_and_execute ros2_sim_msgs/action/PlanAndExecute "{target_type: 1, joint_positions: [0.5, 0.2, -0.3, 0.4, 0.0, -0.5], planning_pipeline: 'pilz_industrial_motion_planner', planner_id: 'PTP', timeout: 10.0, max_velocity_scaling_factor: 0.2, max_acceleration_scaling_factor: 0.1}"Demo scripts:
These run higher-level motion sequences using the same plan_and_execute action interface.
First, start the stack (recommended):
ros2 launch /home/ws/launch_all_with_rviz_custom_planner.launch.pyThen run one of the demos from another sourced terminal:
Pick-and-place (PTP to start + LIN vertical moves, placing on the other side):
ros2 run ros2_sim_motion_planner pick_and_place_demoWelding (PTP to approach + LIN seam tracing with small dwells at corners):
ros2 run ros2_sim_motion_planner welding_demo- External force/wrench injection for disturbance studies
- Deterministic stepping + fixed‑dt execution modes
- Obstacle avoidance (kinematic / Jacobian‑based)
- MPC
- SIL‑oriented tooling (record/replay, noise models, regression tests)
Contributions are welcome! Please open an issue or a pull request if you have any suggestions or improvements.
This project is licensed under the MIT License. See the LICENSE file for details.
