Skip to content

Commit 6ecc0b8

Browse files
authored
Merge branch 'main' into main
2 parents 8d769f0 + 0c321c0 commit 6ecc0b8

File tree

18 files changed

+933
-23
lines changed

18 files changed

+933
-23
lines changed

.github/dependabot.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "github-actions"
4+
directory: "/"
5+
schedule:
6+
interval: "weekly"

.github/workflows/ci.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: CI
2+
on:
3+
workflow_dispatch:
4+
pull_request:
5+
merge_group:
6+
push:
7+
branches:
8+
- main
9+
10+
env:
11+
ROS_DISTRO: humble
12+
13+
jobs:
14+
pre-commit:
15+
runs-on: ubuntu-22.04
16+
steps:
17+
- name: Checkout code from current branch
18+
uses: actions/checkout@v4
19+
- name: Setup ROS
20+
uses: ros-tooling/setup-ros@v0.7
21+
- name: Install dependencies
22+
run: |
23+
sudo apt-get update
24+
sudo rosdep update --rosdistro ${{ env.ROS_DISTRO }}
25+
sudo rosdep install --from-paths . --ignore-src -y -t test --rosdistro ${{ env.ROS_DISTRO }}
26+
- name: Run pre-commit
27+
run: |
28+
pip3 install pre-commit
29+
source /opt/ros/${{ env.ROS_DISTRO }}/setup.bash
30+
pre-commit run --all-files
31+
32+
build_and_test:
33+
needs: pre-commit
34+
runs-on: ubuntu-latest
35+
steps:
36+
- name: Checkout code from current branch
37+
uses: actions/checkout@v4
38+
- name: Set up Docker Buildx
39+
uses: docker/setup-buildx-action@v3
40+
- name: Build in Docker container
41+
uses: docker/build-push-action@v6
42+
with:
43+
context: .
44+
file: docker/Dockerfile
45+
push: false
46+
load: true
47+
tags: mujoco_ros2_control:latest
48+
- name: Test in Docker container
49+
run: docker run --entrypoint "/bin/bash" --rm mujoco_ros2_control:latest -c "colcon test && colcon test-result --verbose"

.github/workflows/stale.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: 'Close stale issues and PR'
2+
on:
3+
schedule:
4+
- cron: '30 1 * * *'
5+
6+
jobs:
7+
stale:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/stale@v9
11+
with:
12+
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 30 days.'
13+
stale-pr-message: 'This PR is stale because it has been open 60 days with no activity. Please ensure the PR is still relevant. If not, please close the PR.'
14+
close-issue-message: 'This issue was closed because it has been stalled for 30 days with no activity.'
15+
days-before-stale: 60
16+
days-before-close: 30
17+
days-before-pr-close: -1
18+
stale-issue-label: 'stale'
19+
stale-pr-label: 'stale'
20+
exempt-issue-labels: 'question,bug,documentation,enhancement,good first issue,help wanted'

doc/index.rst

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,26 @@ Use ``mujoco_ros2_control/MujocoSystem`` for plugin
3333
</joint>
3434
</ros2_control>
3535
36-
Convert URDF model to xml
36+
Convert URDF model to XML
3737
--------------------------
38-
You need to convert the URDF model to a MJCF XML file.
38+
URDF models must be converted to `MJCF XML <https://mujoco.readthedocs.io/en/latest/modeling.html>`_ files.
3939
Make sure to use the same name for the link and joint, which are mapped to the body and joint in Mujoco.
40-
You need to specify <limit> which is mapped to ``range`` in MJCF. For now, there is no way to specify velocity or acceleration limit.
40+
You need to specify <limit> which is mapped to ``range`` in MJCF.
41+
For now, there is no way to specify velocity or acceleration limit.
4142

42-
For force torque sensor, you need to map the sensor to a force sensor and a torque sensor in MJCF since there is no combined force torque sensor in MuJoCo.
43-
The name of each sensor should be ``sensor_name`` + ``_force`` and ``sensor_name`` + ``_torque``.
44-
For example, if you have a force torque sensor called ``my_sensor``, you need to create ``my_sensor_force`` and ``my_sensor_torque`` in MJCF.
43+
For force torque sensors, there is no combined force torque sensor in MuJoCo.
44+
Therefore in ROS, a single force torque sensor must be mapped to both a force sensor and a torque sensor in MJCF.
45+
The name of each sensor must be ``sensor_name`` + ``_force`` and ``sensor_name`` + ``_torque``.
46+
For example, the mapped names for a ROS force torque sensor ``my_sensor`` would be ``my_sensor_force`` and ``my_sensor_torque`` in MJCF.
4547

46-
Check ``mujoco_ros2_control_demos/mujoco_models`` for examples.
48+
The drivers additionally support simulated RGB-D cameras for publishing simulated color images and depth maps.
49+
Cameras must be given a name and be attached to a joint called ``<name>_optical_frame``.
50+
The camera_info, color, and depth images will be published to topics called ``<name>/camera_info``,
51+
``<name>/color``, and ``<name>/depth``, repectively.
52+
Also note that MuJuCo's conventions for cameras are different than ROS's, and which must be accounted for.
53+
An overview is available through the "camera" demo.
54+
55+
For additional information refer to the ``mujoco_ros2_control_demos/mujoco_models`` for examples.
4756

4857
Specify the location of Mujoco models and the controller configuration file
4958
----------------------------------------------------------------------------

mujoco_ros2_control/CMakeLists.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,12 @@ install(TARGETS
7171
)
7272

7373
# TODO: make it simple
74-
add_executable(mujoco_ros2_control src/mujoco_ros2_control_node.cpp src/mujoco_rendering.cpp src/mujoco_ros2_control.cpp)
74+
add_executable(mujoco_ros2_control
75+
src/mujoco_ros2_control_node.cpp
76+
src/mujoco_rendering.cpp
77+
src/mujoco_ros2_control.cpp
78+
src/mujoco_cameras.cpp
79+
)
7580
ament_target_dependencies(mujoco_ros2_control ${THIS_PACKAGE_DEPENDS})
7681
target_link_libraries(mujoco_ros2_control ${MUJOCO_LIB} glfw)
7782
target_include_directories(mujoco_ros2_control
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Copyright (c) 2025 Erik Holum
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy
4+
// of this software and associated documentation files (the "Software"), to deal
5+
// in the Software without restriction, including without limitation the rights
6+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
// copies of the Software, and to permit persons to whom the Software is
8+
// furnished to do so, subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in
11+
// all copies or substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16+
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
// THE SOFTWARE.
20+
21+
#pragma once
22+
23+
#include <string>
24+
#include <vector>
25+
26+
#include "GLFW/glfw3.h"
27+
#include "mujoco/mujoco.h"
28+
#include "rclcpp/rclcpp.hpp"
29+
30+
#include "rclcpp/node.hpp"
31+
#include "rclcpp/publisher.hpp"
32+
#include "sensor_msgs/msg/camera_info.hpp"
33+
#include "sensor_msgs/msg/image.hpp"
34+
35+
namespace mujoco_ros2_control
36+
{
37+
38+
struct CameraData
39+
{
40+
mjvCamera mjv_cam;
41+
mjrRect viewport;
42+
43+
std::string name;
44+
std::string frame_name;
45+
uint32_t width;
46+
uint32_t height;
47+
48+
std::vector<uint8_t> image_buffer;
49+
std::vector<float> depth_buffer;
50+
std::vector<float> depth_buffer_flipped;
51+
52+
sensor_msgs::msg::Image image;
53+
sensor_msgs::msg::Image depth_image;
54+
sensor_msgs::msg::CameraInfo camera_info;
55+
56+
rclcpp::Publisher<sensor_msgs::msg::Image>::SharedPtr image_pub;
57+
rclcpp::Publisher<sensor_msgs::msg::Image>::SharedPtr depth_image_pub;
58+
rclcpp::Publisher<sensor_msgs::msg::CameraInfo>::SharedPtr camera_info_pub;
59+
};
60+
61+
class MujocoCameras
62+
{
63+
public:
64+
explicit MujocoCameras(rclcpp::Node::SharedPtr &node);
65+
66+
void init(mjModel *mujoco_model);
67+
void update(mjModel *mujoco_model, mjData *mujoco_data);
68+
void close();
69+
70+
private:
71+
void register_cameras(const mjModel *mujoco_model);
72+
73+
rclcpp::Node::SharedPtr node_;
74+
75+
// Rendering options for the cameras, currently hard coded to defaults
76+
mjvOption mjv_opt_;
77+
mjvScene mjv_scn_;
78+
mjrContext mjr_con_;
79+
80+
// Containers for camera data and ROS constructs
81+
std::vector<CameraData> cameras_;
82+
};
83+
84+
} // namespace mujoco_ros2_control

mujoco_ros2_control/include/mujoco_ros2_control/mujoco_rendering.hpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,18 @@
2121
#ifndef MUJOCO_ROS2_CONTROL__MUJOCO_RENDERING_HPP_
2222
#define MUJOCO_ROS2_CONTROL__MUJOCO_RENDERING_HPP_
2323

24+
#include <string>
25+
#include <vector>
26+
2427
#include "GLFW/glfw3.h"
2528
#include "mujoco/mujoco.h"
2629
#include "rclcpp/rclcpp.hpp"
2730

31+
#include "rclcpp/node.hpp"
32+
2833
namespace mujoco_ros2_control
2934
{
35+
3036
class MujocoRendering
3137
{
3238
public:
@@ -45,21 +51,26 @@ class MujocoRendering
4551
static void mouse_button_callback(GLFWwindow *window, int button, int act, int mods);
4652
static void mouse_move_callback(GLFWwindow *window, double xpos, double ypos);
4753
static void scroll_callback(GLFWwindow *window, double xoffset, double yoffset);
54+
4855
void keyboard_callback_impl(GLFWwindow *window, int key, int scancode, int act, int mods);
4956
void mouse_button_callback_impl(GLFWwindow *window, int button, int act, int mods);
5057
void mouse_move_callback_impl(GLFWwindow *window, double xpos, double ypos);
5158
void scroll_callback_impl(GLFWwindow *window, double xoffset, double yoffset);
5259

5360
static MujocoRendering *instance_;
61+
5462
mjModel *mj_model_;
5563
mjData *mj_data_;
64+
65+
// Window and primary camera for the simulation's viewer
66+
GLFWwindow *window_;
5667
mjvCamera mjv_cam_;
68+
69+
// Options for the rendering context and scene, all of these are hard coded to defaults.
5770
mjvOption mjv_opt_;
5871
mjvScene mjv_scn_;
5972
mjrContext mjr_con_;
6073

61-
GLFWwindow *window_;
62-
6374
bool button_left_;
6475
bool button_middle_;
6576
bool button_right_;

0 commit comments

Comments
 (0)