ARISE aims towards making industrial HRI more accessible and cost-effective, in particular in healthcare, intra-logistics and manufacturing sectors. These modules hope to present an integration between FIWARE Orion Context Broker and eProsima Vulcanexus to enable context-aware robotic and industrial applications, alongside ROS4HRI as an open-source ROS standard and a set of ROS packages to facilitate the development of Human-Robot Interaction (HRI) capabilities on robots.
This package provides a modular and generic control system for robotic arms (UR, Franka, KUKA, etc.) with integration of:
- Robotic arm control with forward/inverse kinematics
- Artificial vision via RealSense RGB-D
- ArUco marker recognition for dynamic picking
- Gripper control (QB Softhand Industry, Robotiq, RG2, etc.)
- Task system to save and execute movement sequences
┌─────────────────────────────────────────────────────────┐
│ robot_vision_ik_traj_setup.launch.py │
│ (Main Launcher) │
└────────────┬────────────────────────────────────────────┘
│
┌────────┼────────┬──────────┬──────────┐
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
Arm RealSense ArUco Task Gripper
Control Camera Detector Executor Control
| Component | Description | Node/Launch |
|---|---|---|
| Arm Control | Robot arm control + IK trajectory | ik_trajectory_node |
| Vision | RealSense RGB-D camera | rs_launch.py |
| ArUco Detection | Marker recognition | aruco_ros/single.launch.py |
| Task Manager | Save/execute sequences | task_saving_node_complete, task_executor_node_complete |
| Gripper | Gripper control | /gripper/command service |
| Package | Repo | Relation |
|---|---|---|
generic_arm_interfaces |
own submodule | Dependency. Defines the GripperCommand/SavePose services this package implements (/gripper/command, /save_pose). Kept in its own repo — not nested here — so other clients can depend on the service contract without pulling in this whole package. |
This package is a self-contained control layer: it only knows about generic_arm_interfaces. Anything built on top of it (natural-language interfaces, orchestration, ...) is documented in the top-level project README, not here — see modularity note there.
This package depends on generic_arm_interfaces (shared .srv definitions, see table above). If you clone this repo on its own, outside the ros2_arise_vulcanexus_V2 workspace, pull it in with vcstool before building:
vcs import < generic_arm_controller.reposrobot_vision_ik_traj_setup.launch.py is the one launcher this package ships: it starts the robot-agnostic control stack (IK/FK, gripper, task manager) plus optional vision, selecting robot-specific frames/topics purely from generic_arm_controller/config/robots/<robot>.yaml via the robot:= argument — no per-robot Python launch files needed here.
How you invoke it depends on where the robot is running:
- Simulation (Gazebo): don't call it directly — launch it through
arm_gz_bringup/launch/bringup.launch.py, which starts the matching Gazebo/ros2_controlbringup and includes this launcher with the samerobot:=name. See the top-level Multi-Robot Usage Guide for the full argument list (enable_realsense,enable_qb,enable_llm,open_chat). - Real hardware: the robot driver (
ur_robot_driver,franka_bringup, or a separate real-time PC forfr3_real) is started independently, then this launcher is called directly — see Real Hardware Setup below and the top-level README's Real Hardware per Robot section for Franka.
# Default profile (ur10e), no extras
ros2 launch generic_arm_controller robot_vision_ik_traj_setup.launch.py
# Franka FR3 profile
ros2 launch generic_arm_controller robot_vision_ik_traj_setup.launch.py robot:=fr3
# With RealSense
ros2 launch generic_arm_controller robot_vision_ik_traj_setup.launch.py enable_realsense:=true
# With QB Softhand
ros2 launch generic_arm_controller robot_vision_ik_traj_setup.launch.py enable_qb:=true
# Complete: robot + vision + gripper
ros2 launch generic_arm_controller robot_vision_ik_traj_setup.launch.py \
robot:=fr3 enable_realsense:=true enable_qb:=trueThere's no independent gripper:= argument: which gripper driver comes up is tied to the robot (default_gripper_type in that robot's YAML profile; QB Softhand is opt-in via enable_qb). Adding a new robot means adding config/robots/<robot>.yaml — see Adding a New Robot in the top-level README.
Send a target position (x, y, z) and orientation to the arm:
ros2 topic pub /target_cartesian_pose geometry_msgs/msg/PoseStamped \
"{header: {stamp: {sec: 0, nanosec: 0}, frame_id: 'base_link'}, \
pose: {position: {x: 0.5, y: 0.2, z: 0.4}, \
orientation: {x: 0.0, y: 1.0, z: 0.0, w: 0.0}}}" --onceParameters:
x, y, z: Position in meters relative tobase_linkorientation: Quaternion (x, y, z, w) for end-effector orientation
The system supports 3 save modes:
Saves fixed poses relative to the robot base. Ideal for predefined positions.
ros2 service call /save_pose generic_arm_interfaces/srv/SavePose \
"{save_mode: 0, task_name: 'home_pose', reference_frame: ''}"Saves poses relative to the camera. Perfect for interacting with objects at variable positions in the FOV.
ros2 service call /save_pose generic_arm_interfaces/srv/SavePose \
"{save_mode: 1, task_name: 'pre_grasp_from_camera', reference_frame: ''}"Saves poses relative to an ArUco marker. Enables dynamic picking of labeled objects.
ros2 service call /save_pose generic_arm_interfaces/srv/SavePose \
"{save_mode: 2, task_name: 'pick_aruco_dynamic', reference_frame: 'aruco_marker_frame'}"ros2 service call /execute_saved_tasks std_srvs/srv/Trigger "{}"ros2 service call /clear_saved_poses std_srvs/srv/Trigger "{}"ros2 service call /gripper/command generic_arm_interfaces/srv/GripperCommand "{command: 'close'}"ros2 service call /gripper/command generic_arm_interfaces/srv/GripperCommand "{command: 'open'}"ros2 service call /qb_softhand_industry_communication_handler/activate_motors \
qb_softhand_industry_srvs/srv/Trigger "{}"Close completely (position: 3000)
ros2 service call /qb_softhand_industry_communication_handler/set_command \
qb_softhand_industry_srvs/srv/SetCommand \
"{max_repeats: 1, set_commands: true, position_command: 3000}"Open completely (position: 0)
ros2 service call /qb_softhand_industry_communication_handler/set_command \
qb_softhand_industry_srvs/srv/SetCommand \
"{max_repeats: 1, set_commands: true, position_command: 0}"Range: 0 (open) to 3500 (closed)
Launched automatically with enable_realsense:=true, or manually:
ros2 launch realsense2_camera rs_launch.pyAvailable topics:
/camera/color/image_raw- RGB image/camera/depth/image_rect_raw- Depth map/camera/color/camera_info- Camera intrinsic parameters
ros2 launch aruco_ros single.launch.py \
image_topic:=/camera/color/image_raw \
camera_info_topic:=/camera/color/camera_info \
marker_size:=0.15 \
marker_id:=0 \
camera_frame:=camera_linkOutput: aruco_marker_frame - TF of detected marker
ros2 launch ur_simulation_gazebo ur_sim_control.launch.py \
description_package:=tools_config \
description_file:=ur_camera_robotiq.urdf.xacro \
ur_type:=ur10e-
Network Configuration:
- PC: IP address
192.168.56.1 - UR10e: IP address
192.168.56.100
- PC: IP address
-
UR+ Panel Setup:
- Access URCap → External Control
- Set PC address:
192.168.56.1
ros2 launch ur_robot_driver ur_control.launch.py \
ur_type:=ur10e \
robot_ip:=192.168.56.100 \
launch_rviz:=true \
initial_joint_controller:=scaled_joint_trajectory_controllerros2 launch generic_arm_controller robot_vision_ik_traj_setup.launch.py \
enable_realsense:=true enable_qb:=truePosition the object with ArUco marker (e.g., ID=0) in the camera's FOV.
Pre-grasp relative to camera:
ros2 service call /save_pose generic_arm_interfaces/srv/SavePose \
"{save_mode: 1, task_name: 'pre_grasp', reference_frame: ''}"Grasp relative to ArUco:
ros2 service call /save_pose generic_arm_interfaces/srv/SavePose \
"{save_mode: 2, task_name: 'grasp', reference_frame: 'aruco_marker_frame'}"Absolute home:
ros2 service call /save_pose generic_arm_interfaces/srv/SavePose \
"{save_mode: 0, task_name: 'home', reference_frame: ''}"ros2 service call /execute_saved_tasks std_srvs/srv/Trigger "{}"The robot will execute: pre-grasp → grasp → home
Instead of running the workflow above by hand, validate_pipeline does move → confirm arrival (via /fk_pose) → save → replay → cleanup on its own and prints a PASS/FAIL summary (exit code 1 on failure):
ros2 run generic_arm_controller validate_pipeline
# or, for a robot other than UR10e:
ros2 run generic_arm_controller validate_pipeline --base-frame fr3_link0 --pose1 0.3,0.0,0.5 --pose2 0.3,0.0,0.3See the main README's End-to-End Validation Tutorial for the manual, step-by-step equivalent.
| Problem | Solution |
|---|---|
[ERROR] Failed to detect ArUco marker |
Increase brightness, check marker ID, verify size |
IK not converging |
Target position unreachable, check joint limits |
RealSense not found |
Run ros2 run realsense2_camera list_devices to verify connection |
Gripper not responding |
Verify USB/ethernet communication, run activate_motors |
generic_arm_controller/
├── launch/
│ └── robot_vision_ik_traj_setup.launch.py (control stack: IK/FK, gripper, task manager, vision)
├── generic_arm_controller/
│ ├── ik_trajectory_node.py
│ ├── fk_node.py
│ ├── gripper_manager.py
│ ├── task_saving_node_complete.py
│ ├── task_executor_node_complete.py
│ ├── urdf_loader.py
│ ├── marker_lock.py
│ ├── check_saved_deltas.py
│ └── validate_pipeline.py
├── config/
│ └── robots/
│ ├── ur10e.yaml
│ ├── fr3.yaml
│ └── fr3_real.yaml
└── calibration_results/
└── hand_eye_transform_<robot>.yaml
Robot-agnosticism lives entirely in config/robots/<robot>.yaml (base_frame, end_effector_frame, joint_names, action_server_name, default_gripper_type, IK tuning), read by every node above — there is no per-robot Python code or per-robot launch file in this package. The Gazebo/ros2_control side of "swap robot configurations" lives one level up, in the arm_gz_bringup package (arm_gz_bringup/launch/<robot>.launch.py), orchestrated together with this package's launcher by arm_gz_bringup/launch/bringup.launch.py — see the top-level README's Multi-Robot Usage Guide and Adding a New Robot.
- UR Driver: https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver
- QB Softhand: https://index.ros.org/r/qb_softhand_industry/
- ArUco ROS: https://github.com/pal-robotics/aruco_ros
- RealSense: https://github.com/IntelRealSense/realsense-ros
- PyIK (Pinocchio): https://github.com/stack-of-tasks/pinocchio
Apache-2.0
Contributions are welcome! Please feel free to submit a Pull Request.
Last Updated: June 2026 Maintainer: JOiiNT-LAB
Funded by the European Union. Views and opinions expressed are however those of the author(s) only and do not necessarily reflect those of the European Union or HADEA. Neither the European Union nor the granting authority can be held responsible for them.
