RoTools is an all-in-one ROS package for high-level robotic task scheduling, visual perception, path planning, simulation, and direct-/tele-manipulation control. It leverages BehaviorTree to deliver fast task construction and coordination, and provides various utilities to bridge the gap between real/simulated robot and the high level task scheduler.
The packages compose of two components: roport and rotools.
This module provides the application level entrance ports of the RoTools package. It is a middleware that allows using rotools cpp/python interfaces in ROS environment. It provides:
- MoveIt Python Server for controlling the robot's single kinematic chain using MoveIt's Python interface.
- Sensing Server that bridges the perception modules outside the ROS environment (like those run in Python3) to ROS via HTTP.
- Planner Server bridges ROS modules with the planning algorithm outside the ROS environment (running in Python3 or on another server on the local network) via HTTP. This server is designed for online control, that given the current state, it will query the algorithm for the next state. For now, the states are Cartesian poses.
- Snapshot Server enables recording various types of ROS msgs to files.
- Websocket Client enables transmitting ROS msgs among two PCs through ROS Bridge.
- Xsens Server converting the live stream from Xsens MVN Awinda motion capture suit to ROS pose messages.
- OptiTrack Client converting streams from OptiTrack socket server to pose msgs.
- Hardware/Simulation interfaces adapted for a variety types of robots.
- MoveIt CPP Server simultaneously controlling multiple kinematic chains of a robot with MoveIt's action interface.
- Path Planning Interface utilizes Humanoid Path Planner to plan whole-body collision free paths for high-dof robots.
- Msg Converter converts msg from one type to another, be able to modify the name field, and enables smoothly start the control of certain joint groups.
- Task Scheduler using behavior tree for task scheduling. A bunch of general purpose services and a node library are provided for building the task tree fast.
This Python package hosted under src/
is a versatile robotic toolbox aimed for fast prototyping. It includes
foundational modules for robotic problems including path & trajectory planning, kinematics & dynamics calculation,
sensing, transformation calculation, simulation, and so forth.
Recommended: Ubuntu 20.04 with ROS Noetic, Python 3.8.
This software is continuously built using catkin_make
and catkin tools
on 20.04.
The support of 18.04 is no longer maintained.
This package has been developed as we use the following robots featuring sophisticated design, yet the package itself is agnostic to robot type and can be used to various types including robot arms and mobile manipulators.
- Walker from UBTech
- CURI/Curiosity from CLOVER Lab CUHK
Groot is a Graphical Editor, written in C++ and Qt, to create BehaviorTrees. The tree files should be better edited using this software.
Click to expand
Follow these steps to install it:
sudo apt install qtbase5-dev libqt5svg5-dev libzmq3-dev libdw-dev
cd ~ && git clone https://github.com/BehaviorTree/Groot.git && cd Groot
git submodule update --init --recursive
mkdir build; cd build
cmake ..
make
Run the script in Groot/build
to start it:
~/Groot/build/Groot
The installation of 'RoTools' with all its dependencies is extremely simple in only 2 steps:
-
Clone the repo from GitHub to your
$HOME
folder:cd ~ && git clone https://github.com/DrawZeroPoint/RoTools.git
-
Install prerequisites with setup_tools.sh. Rerun the script is safe.
cd ~/RoTools/misc && ./setup_tools.sh
By default, the script will install ROS, CartesI/O, pinocchio, hpp, ocs2, MuJoCo, and two tools: sublime text and JetBrains toolbox to your computer. This is extremely helpful for a brand new machine. You can also install install some of them based on what you need, please see the script or use setup_tools.sh --help for details.
Note that in the above process, a symlink for RoTools will be created under the ROS workspace (assume '~/catkin_ws' here). The symlink trick allows flexible support for multiple ROS workspaces, so you do not need to manage more than one RoTools package.
The pipeline of using RoTools for a particular robot involves:
Create a description package for the robot you want to use, you can refer to curiosity or walker repo. This may involve:
-
Create a launch file named
<robot>_moveit.launch
for bringing up the MoveIt interfaces, hardware interfaces, and optionally a converter for remapping standard measure/control topics to those used by the real/simulated robot. -
Create a launch file named
<robot>_roport.launch
for bridging RoPort MoveIt server, which essentially is a middleware between the MoveIt interface and the task scheduler. It could disassemble various type of movements for MoveIt to plan and execute. -
Arrange the tasks with BT using Groot. Note that a predefined BT node package (palette.xml) has been provided, you can load that into Groot for a quick start. After generating the xml file describing the task, feed it as a parameter of the
<robot>_task.launch
.
After finishing these preparations, you can run the demo by
- Start the simulator or connect to the real robot. Do not forget starting
roscore
when using the simulator. - Launch
<robot>_moveit.launch
. - Launch
<robot>_roport.launch
. - Launch
<robot>_task.launch
.
CartesI/O is a whole-body motion planning software developed in ADVR, Istituto Italiano di Tecnologia. It has not been added to the ROS distribution and hence install it is needed for proceeding the next steps.
-
Prepare the URDF file and SRDF file of the robot you use. Certain rules should be followed.
-
Create a launch file named as
<robot>_cartesio.launch
.
After the preparations, you can
-
launch the file by:
roslaunch roport <robot>_cartesio.launch
This will show a RViz window if you did not set gui:=false. See the explanation of the arguments by launch with
--ros-args
. -
In RViz, right-click the interactive marker (IM) in scene, choose
continous control
, then you can control the robot by dragging the IM.
The IMU based motion capture suit provided by Xsens could be used as a direct tele-operation input source for controlling the robot. RoTools enables converting the motion capture stream sent via UDP to ROS messages. To establish the conversion:
-
Configure the MVN Animate/Analyze software, enable transmitting the live stream to the receiving machine's IP (the machine running RoTools). The default port number is 9763. You need to get a license for the MVN software to use the streaming function.
-
Make sure the publisher and receiver machines are in the same local network. From now on, we assume the receiver's network as:
inet 192.168.13.234 netmask 255.255.255.0 broadcast 192.168.13.255
While the publisher is:
inet 192.168.13.102 netmask 255.255.255.0 broadcast 192.168.13.255
The
ufw
of the receiver should be configured to allow incoming access (note 13 is variable while 0/24 is fixed):sudo ufw allow from 192.168.13.0/24
-
Launch the Xsens server
roslaunch roport roport_xsens.launch
By default, the server will publish poses on topics: /xsens/all_poses
, /xsens/body_poses
, /xsens/left_tcp
,
/xsens/right_tcp
, /xsens/left_sole
, /xsens/right_sole
. The former two are in PoseArray
format, the latter ones
are in PoseStamped
.
body_poses
are the poses of body segments without hand segments; left_tcp
is the left palm pose;
right_tcp
is the right palm pose. left_sole
is the left sole pose; right_sole
is the right sole pose. When
standing in T-pose, the TCP poses and sole poses are illustrated as:
These poses all reference to the reference_frame, which could be 'Pelvis' or 'T8'. You can set the reference frame in
the launch file. If the frame name is not within these two, a given one will be used. If empty string is given, the
default one world
will be used.
You can use remap
in the launch file to remap some of these to other topic names.
The server will also publish hand joint states on topics: /xsens/left_hand_js
, and /xsens/right_hand_js
. The joint
states for each hand compose of 10 values ranging from 0 to 1, where 0 is fully stretch, 1 is fully bend.
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|
thumb_j1 | thumb_j2 | index_j1 | index_j2 | middle_j1 | middle_j2 | ring_j1 | ring_j2 | pinky_j1 | pinky_j2 |
Note: j1 is the joint between metacarpals (parent) and proximal phalanges (child); j2 is the angle between proximal phalanges and intermediate/distal phalanges (distal is used only for the thumb). For the four fingers other than the thumb, the joints between intermediate and distal phalanges are not presented.
For safety concern, you need to activate the conversion by:
Press the Alt
key (either left or right) on the keyboard. This will switch the status from deactive
to active
. To
change back, press Alt
again. The last output in the console will indicate the current status.
Alternatively, you can use:
rosservice call /xsens/enable "data: true"
The initial state is in deactivate state, to disable conversion, set data
as false.
First, you should start the server on the Windows side with start_server.py:
python start_server.py
Then, on the linux side, run:
roslaunch roport roport_optitrack_client.launch
This interface inherits the hardware_interface
in ros_control
. It gets measured joint states via one or more topics
from the real robot or the simulator. Meanwhile, it sets the joint states commands down to the robot or the simulator
via one or more topics.
To properly use this, you need to set the joint states' getter/setter topics in the launch file like this:
<node pkg="roport" type="roport_robot_interface" name="roport_robot_interface" output="screen">
<param name="joint_name_param_id" value="/walker/hardware_interface/joints"/>
<rosparam param="measure_joint_states_id">
[
"/walker/leftLimb/joint_states",
"/walker/rightLimb/joint_states",
]
</rosparam>
<rosparam param="control_joint_states_id">
[
"/walker/leftLimb/command",
"/walker/rightLimb/command",
]
</rosparam>
<rosparam param="joint_states_group">
[
[
"left_limb_j1", "left_limb_j2", "left_limb_j3", "left_limb_j4",
"left_limb_j5", "left_limb_j6", "left_limb_j7"
],
[
"right_limb_j1", "right_limb_j2", "right_limb_j3", "right_limb_j4",
"right_limb_j5", "right_limb_j6", "right_limb_j7"
]
]
</rosparam>
</node>>
The param measure_joint_states_id
and control_joint_states_id
must be set. Note that these topic ids have
leading /
. Besides, the joint_states_name_group
should be set for each getter and setter topics. If it is not set, there should be only one getter and one setter topic,
in this case, the algorithm will use all names set in the parameter joint_name_param_id
.
This converter will convert sensor_msgs::JointState
type message from one topic (source) to another (target). Be
different with remap
which only change the topic's id but not touching the contents, it could:
- Altering the
name
field. User can specify the names for the joints to care about and define the new names of their correspondences in the converted msg. - Smooth the start procedure. Usually for control commands, the target configurations are different with the robot's current configuration. Directly apply the commands to the robot will cause huge movement not safe to constraints. User can specify which group to smooth during start, letting the group slowly reaching the target configurations and then follow subsequent commands.
- Convert joint state message from one type to another, including customized types, and providing arguments to the customized ones.
Note
- This converter cannot smooth effort commands which are not changed during smooth.
- If the smooth has finished, no more smooth will happen unless rerun the program.
To use this function, we need to define the following parameters in the launch file or load them from a yaml file:
Name | Type | Explanations (the outer lists all with the same length are for joint groups, following we only explain the contents) |
---|---|---|
source_joint_groups |
list[list[str]] | Joint names defined as a source_joint_group . They are adopted for selecting certain names from source_js_topic . |
target_joint_groups |
list[list[str]] | Joint names having one-on-one correspondence with source_joint_group . Target joint values will be under these new names. |
source_js_topics |
list[str] | Topic id source_js_topic that should be converted to target_js_topic . |
target_js_topics |
list[str] | Topic ids converted from source_js_topic . |
target_types |
list[str] | Target topic type. By default, the type string is sensor_msgs/JointState , other types are also supported by modifying the code. Its size must equal to target_js_topics . |
target_args |
list[int] | Arguments defining the customized control arg. For sensor_msgs/JointState , it is ignored. Its size must be equal to target_js_topics. |
enable_smooth_start |
list[int] | Flag for smooth start. If larger than 0, Ruckig will be used to smoothly move the enabled groups from the current configurations to the target. Its size equals to source_js_topics . |
start_ref_topics |
list[str] | Topic id for monitoring the robot state and initializing the start configurations for smoothing enabled groups. |
max_vel |
map[str, double] | For each joint name, define its maximum allowed velocity during smooth movement. The name could be either in source_joint_group or target_joint_group (same for max_acc and max_jerk). |
max_acc |
map[str, double] | For each joint name, define its maximum acceleration during smooth movement. |
max_jerk |
map[str, double] | For each joint name, define its maximum jerk during smooth movement. |
This server records ROS msgs to local files depending on the msg types. Text types, like JointState, will be saved in CSV file. Image types are directly saved as images. Currently, we support:
Type | Service to call | Srv |
---|---|---|
JointState | /save_joint_state | SaveJointState |
Odometry | /save_odometry | SaveOdometry |
Pose | /save_pose | SavePose |
CompressedImage | /save_image | SaveImage |
Refer to roport_snapshot_server.launch for launching the function. Topics you
want to take snapshot must be registered with ROS parameters and be published by other nodes. You can specify which
topic to record by calling aforementioned services By default, the saved files are located at ~
.
-
The name should obey the CamelCase convention. Each word in the name should avoid meaningless abbreviation, for example, Object is better than Obj.
-
The first word should only be
Get
,Sense
, orExecute
, whereGet
means retrieve some information from within the software, such as all names of planning groups, or robot joint states;Sense
means get information from outside environment, such as get the pose of an object; andExecute
means interact with the environment, such as open a switch, move the robot arm, or add a collision object into the planning scene. -
If the second word is
Group
, it means the service operates on a planning group in MoveIt. Similarly, if the word isAll
, it means applying to all planning groups. If the context is clear, such as a collision object could only be added to a group, theGroup
could be omitted. -
For the third and the following words,
Plan/Plans
means a trajectory,Pose/Poses
means the 6-DoF Cartesian pose in workspace,JointStates
means the joint values in C-space.
Add the following comment on top of each .srv file:
Here [opt]
stands for optional param, whose value could be not given. In this case, note that the default value will
be used.
# Brief explanation about the service
# Requests
# param [opt]: Explanation goes here
# ...
# Response
# param [opt]: Explanation goes here
# ...
The response of the service should always contain:
uint8 SUCCEEDED=0
uint8 FAILED=1
uint8 result_status
For these parameters the comment could be omitted.
The MoveIt Python Server does not support simultaneously execution for multiple end-effectors. To circumvent this, you can use the MoveIt CPP Server instead.