This repository contains mc_rtc robot modules for tools — end-effectors, sensors, and other peripherals — that can be attached to any robot supported by the mc_rtc framework.
Each tool lives in its own top-level folder and is built as an independent, opt-in CMake module. A tool is either self-contained (ships its own URDF/meshes) or depends on an official ROS description package for its geometry — see Available Robot Tools below.
Prerequisite: mc_rtc must already be installed.
git clone https://github.com/isri-aist/mc_robot_tools.gitSome tools depend on an external ROS description package for their geometry (see Available Robot Tools). Fetch and build the ones you need with vcstool and colcon, then source the resulting workspace so find_package() can locate them:
mkdir -p ros2_ws/src
vcs import --input mc_robot_tools/dependencies.repos ros2_ws/src
cd ros2_ws
colcon build
source install/setup.bash
cd ..cd mc_robot_tools
mkdir -p build && cd build
cmake ..Turn on the tools you want to build, then build and install:
ccmake ..
# Turn on the WITH_<module_name> option(s) you need
# [c] Configure > [e] Exit > [g] Generate
make
sudo make install| Tool Module | Dependency |
|---|---|
| bota_sensor | bota_driver_ros2 |
| ds4 | None |
| plate | None |
| realsense_camera | None |
| robotiq_gripper | ros2_robotiq_gripper/robotiq_description |
| robotiq_hande | robotiq_hande_description |
| screw | None |
On their own, these modules just describe a tool's geometry — they don't do anything. To use one, attach it to a robot module:
auto robot = mc_rbdyn::RobotLoader::get_robot_module("<robot_name>");
auto tool = mc_rbdyn::RobotLoader::get_robot_module("<tool_name>");
auto robot_tool = robot.connect(*tool, "<robot_frame>", "<tool_frame>", "",
mc_rbdyn::RobotModule::ConnectionParameters{}.X_other_connection(sva::RotZ(0.0)));
// Add links for self collisions
const double COL_I = 0.03;
const double COL_S = 0.015;
const double COL_D = 0.0;
auto addToolCollisions = [COL_I, COL_S, COL_D](mc_rbdyn::RobotModule &module,
const std::vector<std::string> &robot_collision_links,
const std::vector<std::string> &tool_collision_links) {
for (const auto &robot_link : robot_collision_links)
{
for (const auto &tool_link : tool_collision_links)
{
module._minimalSelfCollisions.push_back({robot_link, tool_link, COL_I, COL_S, COL_D});
}
}
module._commonSelfCollisions = module._minimalSelfCollisions;
};
addToolCollisions(robot_tool, {"<robot_link_1>", "<robot_link_2>", "<robot_link_3>"},
{"<tool_link_1>", "<tool_link_2>", "<tool_link_3>"});Note that none of these constraints are added to the solver automatically — you still need to define and add them yourself.
Every tool module falls into one of two categories (see the table above for which is which):
- Self-contained: ships its own URDF/meshes, no external dependencies.
- ROS-dependent: derives its URDF from an external ROS description package.
If you want to add a new tool, use the existing modules as reference:
- Self-contained examples: Check out the ds4, plate, or realsense_camera directories.
- ROS description examples: Check out the bota_sensor, robotiq_gripper, robotiq_hande directories.
Each tool's top-level CMakeLists.txt is a standard CMake project (cmake_minimum_required(), project(), find_package(mc_rtc REQUIRED), ...) that then calls two macros from cmake/mc_rtc_macros.cmake:
mc_rtc_generate_robot_description(MODELS <model1> [model2 ...])generates and installs the URDF/RSDF/meshes. It auto-detectsxacro/,urdf/,rsdf/andmeshes/under the module's own directory, so most modules only need to passMODELS. PassXACRO_PATH/URDF_DIR/RSDF_DIR/MESHESexplicitly to point a module at a folder outside its own directory (e.g. an upstream ROS description package — see bota_sensor/CMakeLists.txt). It also defaults the build target name from the folder name (generate-<new_tool>-urdf) and exposesMC_DATA_PATH/MC_RSDF_DIR/etc. forsrc/config.in.h.mc_rtc_generate_robot_module()auto-discovers and adds thesrc/,yaml/andtests/subdirectories if they exist.
Each tool follows this layout:
<new_tool>
├── CMakeLists.txt
├── meshes
│ └── <part_name>.stl
├── rsdf
│ └── <new_tool>.rsdf
├── src # C++ module (or yaml/, see "Alternative: YAML-based modules")
│ ├── CMakeLists.txt
│ ├── config.in.h
│ ├── <new_tool>.cpp
│ └── <new_tool>.h
├── tests
│ ├── CMakeLists.txt
│ └── loader.in.cpp
└── urdf (or xacro)
└── <new_tool>.in.urdf- Copy one of the reference modules above and rename to
<new_tool> - Update
<new_tool>/CMakeLists.txt: setROBOT_NAMEand theMODELSpassed tomc_rtc_generate_robot_description(), e.g.:See How module generation works above for what gets auto-detected vs. needs to be passed explicitly (XACRO_PATH, multiple MODELS, ...).cmake_minimum_required(VERSION 3.22) set(ROBOT_NAME <new_tool>) project( mc_${ROBOT_NAME} LANGUAGES CXX VERSION 1.0.0) set(CXX_DISABLE_WERROR 1) set(CMAKE_CXX_STANDARD 17) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) include(CTest) find_package(mc_rtc REQUIRED) mc_rtc_generate_robot_description(MODELS ${ROBOT_NAME}) mc_rtc_generate_robot_module()
- Add the corresponding
WITH_<NEW_TOOL>option to the top-levelCMakeLists.txt:option(WITH_<NEW_TOOL> "Build <new_tool> module" OFF) # ... if(WITH_<NEW_TOOL>) add_subdirectory(<new_tool>) endif()
- Add the corresponding conversion in the top-level
CMakeLists.txt:foreach(opt ... <NEW_TOOL>) - Add the tool to the CMake-generated header include/mc_robot_tools/mc_robot_tools.in.h:
inline std::vector<std::string> list<NewTool>() { // clang-format off const bool WITH_<NEW_TOOL>_BOOL = @WITH_<NEW_TOOL>_BOOL@; // clang-format on if(WITH_<NEW_TOOL>_BOOL) { return {"<Model1>", "<Model2>", ...}; } return {}; }
-
Update
<new_tool>/src/<new_tool>.h:- Update structure name to
<NewTool>RobotModule - Declare the required override methods:
std::string baseFrame() const override; std::string wrenchFrame() const override; // optional — defaults to baseFrame std::vector<std::string> collisionLinks() const override; // optional — defaults to empty sva::PTransformd defaultMountingTransform() const override; // optional — defaults to identity
- Update
MC_RTC_ROBOT_MODULE()with the full list of robot names your module exposes- It is possible to conditionally register different subsets of modules by adjusting names dynamically at runtime. However, consider splitting them into multiple tool modules for simplicity if possible.
- Update
create()to return an instance of your new class for each supported name.
- Update structure name to
-
Update
<new_tool>/src/<new_tool>.cpp:- Constructor: call
ConnectableRobotModule(MC_DATA_PATH, name)and initialize the URDF, and setrsdf_dir. - Implement the override methods declared in the header:
baseFrame(),wrenchFrame(),collisionLinks(),defaultMountingTransform().
- Constructor: call
- Add the URDF (or xacro template) to
<new_tool>/urdf/(or<new_tool>/xacro/) - Add the RSDF file to
<new_tool>/rsdf/<robot_name>.rsdfmatching the URDF's link names- Consider following this tutorial or using this repository export rsdf files.
- Update
TEST_MODELSin<new_tool>/tests/CMakeLists.txtwith the exposed robot names - Run ctest --verbose locally to verify the module loads without segfaults or unresolved frames
- Add
WITH_<NEW_TOOL>option to step "Build and test" in.github/workflows/build.yml.- If the tool needs a ROS description package: add it to dependencies.repos and to the
--packages-selectlist in the "Install ROS description packages" step.
- If the tool needs a ROS description package: add it to dependencies.repos and to the
- Update this README with the new tool name, dependencies, any notable configuration options.
Robot modules can also be programmed with yaml instead of C++ (check this repository for the expected layout: a yaml/ folder with its own CMakeLists.txt that configure_file()s the robot description onto ${MC_SHARE_DIR} and installs an alias entry to ${MC_ROBOTS_ALIASES_DIRECTORY}).
mc_rtc_generate_robot_module() auto-discovers a yaml/CMakeLists.txt the same way it does src/CMakeLists.txt, so a tool can ship a yaml/ folder instead of (or alongside) src/.
However, this is not the preferred method since we cannot expose baseFrame, wrenchFrame, collisionLinks, or the available robot list to other programs using these tools.