ROS2 Package
The MANUS ROS2 package is a ROS2 wrapper around the MANUS C++ SDK. This package allows you to integrate MANUS gloves into your ROS2 project and provides a ROS2 interface for MANUS glove data.
Overview
The ROS2 package publishes MANUS glove data as ROS2 topics. A custom message type is used to represent glove data and exposes the following data for each glove connected:
- Raw skeleton data: The raw skeleton data represented as a list of joint positions.
- Ergonomics values: The ergonomics values represented as a list of joint angular rotations.
- Raw sensor data: The raw sensor data represented as a list of sensor positions and rotation relative to the glove source (only available for MANUS Metagloves Pro series gloves).
Please refer to the getting started guide for more information on the package.
Installation
For installation instructions, please refer to the getting started guide's installation section.
Structure
The MANUS ROS2 package publishes glove data as ROS2 topics. For each glove connected, a subsequent topic is created. The topics are named according to an incremental naming scheme, starting from manus_glove_0
and incrementing for each glove connected.
Each glove is represented as a ManusGlove
message type. The message types are structured as follows:
ManusGlove
Field | Type | Description |
---|---|---|
glove_id |
int32 | The ID of the MANUS glove device |
side |
string | The side of the glove (left or right) |
raw_node_count |
int32 | The number of raw skeleton nodes |
raw_nodes |
ManusRawNode[] | Array of raw skeleton nodes |
ergonomics_count |
int32 | The number of ergonomics data points |
ergonomics |
ManusErgonomics[] | Array of ergonomics data |
raw_sensor_orientation |
geometry_msgs/Quaternion | Orientation of the raw wrist (Only for Metaglove Pro series gloves) |
raw_sensor_count |
int32 | The number of raw sensors (Only for Metaglove Pro series gloves) |
raw_sensor |
geometry_msgs/Pose[] | Array of raw sensor data (Only for Metaglove Pro series gloves) |
Manus Raw Node
Field | Type | Description |
---|---|---|
node_id |
int32 | The ID of the node |
parent_node_id |
int32 | The ID of the parent node |
joint_type |
string | The type of joint (e.g., wrist, finger, etc.) |
chain_type |
string | The type of chain (e.g., mcp, pip, etc.) |
pose |
geometry_msgs/Pose | The pose of the node in 3D space |
Manus Ergonomics
Field | Type | Description |
---|---|---|
type |
string | The type of ergonomics data (which joint) |
value |
float32 | The value of the ergonomics data (what angle) |
This data is published at a rate of 120Hz by default and can be subscribed to by any ROS2 node.
Type representations
Within the topics, enums are mapped to strings to represent the different data properties. The following tables show the enum values and their string representations.
Side
Enum Value | String Representation |
---|---|
Side_Left |
Left |
Side_Right |
Right |
Default | Invalid |
ChainType
Enum Value | String Representation |
---|---|
ChainType_Arm |
Arm |
ChainType_Leg |
Leg |
ChainType_Neck |
Neck |
ChainType_Spine |
Spine |
ChainType_FingerThumb |
Thumb |
ChainType_FingerIndex |
Index |
ChainType_FingerMiddle |
Middle |
ChainType_FingerRing |
Ring |
ChainType_FingerPinky |
Pinky |
ChainType_Pelvis |
Pelvis |
ChainType_Head |
Head |
ChainType_Shoulder |
Shoulder |
ChainType_Hand |
Hand |
ChainType_Foot |
Foot |
ChainType_Toe |
Toe |
Default | Invalid |
JointType
Enum Value | String Representation |
---|---|
FingerJointType_Metacarpal |
MCP |
FingerJointType_Proximal |
PIP |
FingerJointType_Intermediate |
IP |
FingerJointType_Distal |
DIP |
FingerJointType_Tip |
TIP |
Default | Invalid |
ErgonomicsType
Enum Value | String Representation |
---|---|
ErgonomicsDataType_LeftFingerIndexDIPStretch |
IndexDIPStretch |
ErgonomicsDataType_RightFingerIndexDIPStretch |
IndexDIPStretch |
ErgonomicsDataType_LeftFingerMiddleDIPStretch |
MiddleDIPStretch |
ErgonomicsDataType_RightFingerMiddleDIPStretch |
MiddleDIPStretch |
ErgonomicsDataType_LeftFingerRingDIPStretch |
RingDIPStretch |
ErgonomicsDataType_RightFingerRingDIPStretch |
RingDIPStretch |
ErgonomicsDataType_LeftFingerPinkyDIPStretch |
PinkyDIPStretch |
ErgonomicsDataType_RightFingerPinkyDIPStretch |
PinkyDIPStretch |
ErgonomicsDataType_LeftFingerIndexPIPStretch |
IndexPIPStretch |
ErgonomicsDataType_RightFingerIndexPIPStretch |
IndexPIPStretch |
ErgonomicsDataType_LeftFingerMiddlePIPStretch |
MiddlePIPStretch |
ErgonomicsDataType_RightFingerMiddlePIPStretch |
MiddlePIPStretch |
ErgonomicsDataType_LeftFingerRingPIPStretch |
RingPIPStretch |
ErgonomicsDataType_RightFingerRingPIPStretch |
RingPIPStretch |
ErgonomicsDataType_LeftFingerPinkyPIPStretch |
PinkyPIPStretch |
ErgonomicsDataType_RightFingerPinkyPIPStretch |
PinkyPIPStretch |
ErgonomicsDataType_LeftFingerIndexMCPStretch |
IndexMCPStretch |
ErgonomicsDataType_RightFingerIndexMCPStretch |
IndexMCPStretch |
ErgonomicsDataType_LeftFingerMiddleMCPStretch |
MiddleMCPStretch |
ErgonomicsDataType_RightFingerMiddleMCPStretch |
MiddleMCPStretch |
ErgonomicsDataType_LeftFingerRingMCPStretch |
RingMCPStretch |
ErgonomicsDataType_RightFingerRingMCPStretch |
RingMCPStretch |
ErgonomicsDataType_LeftFingerPinkyMCPStretch |
PinkyMCPStretch |
ErgonomicsDataType_RightFingerPinkyMCPStretch |
PinkyMCPStretch |
ErgonomicsDataType_LeftFingerThumbMCPSpread |
ThumbMCPSpread |
ErgonomicsDataType_RightFingerThumbMCPSpread |
ThumbMCPSpread |
ErgonomicsDataType_LeftFingerThumbMCPStretch |
ThumbMCPStretch |
ErgonomicsDataType_RightFingerThumbMCPStretch |
ThumbMCPStretch |
ErgonomicsDataType_LeftFingerThumbPIPStretch |
ThumbPIPStretch |
ErgonomicsDataType_RightFingerThumbPIPStretch |
ThumbPIPStretch |
ErgonomicsDataType_LeftFingerThumbDIPStretch |
ThumbDIPStretch |
ErgonomicsDataType_RightFingerThumbDIPStretch |
ThumbDIPStretch |
ErgonomicsDataType_LeftFingerMiddleMCPSpread |
MiddleSpread |
ErgonomicsDataType_RightFingerMiddleMCPSpread |
MiddleSpread |
ErgonomicsDataType_LeftFingerRingMCPSpread |
RingSpread |
ErgonomicsDataType_RightFingerRingMCPSpread |
RingSpread |
ErgonomicsDataType_LeftFingerPinkyMCPSpread |
PinkySpread |
ErgonomicsDataType_RightFingerPinkyMCPSpread |
PinkySpread |
Default | Invalid |
Settings
Inside the ManusDataPublisher.hpp
header file the following settings are exposed to configure the layer.
ConnectionType m_ConnectionType = ConnectionType::ConnectionType_Integrated;
std::string m_Ip = "";
//Coordinate system settings
bool m_WorldSpace = true;
CoordinateSystemVUH m_CoordinateSystem = {AxisView::AxisView_XFromViewer, AxisPolarity::AxisPolarity_PositiveZ, Side::Side_Right, 1.0f};
HandMotion m_HandMotion = HandMotion::HandMotion_None;
ConnectionType
The ConnectionType
enum is used to specify the connection type of the MANUS ROS2 package. This allows you to choose between the integrated and remote modes.
The libManusSDK.so
library included (ManusSDK/lib/
) contains support for both integrated
and remote
modes. This means that all the prerequisites need to be installed. When not able or willing to install the remote
prerequisites, the libManusSDK.so
can be replaced with the libManusSDK_Integrated.so
library which is located in the same folder.
This can either be done by renaming the libManusSDK_Integrated.so
to libManusSDK.so
or by changing the following lines in the CMakeLists.txt
file.
#Line 27
target_link_libraries(manus_data_publisher ManusSDK_Integrated ncurses)
#Line 39
set(LIBRARY_FILE ${LIBRARY_DIR}/libManusSDK_Integrated.so)
The m_Ip
string is used to specify the IP address of the remote server when using the remote connection type, if the string is left empty the first available connection will be used.
Coordinate System
The coordinate system settings are used to define the coordinate system the glove data nodes are represented in.
The m_WorldSpace
boolean is used to specify whether the glove data is represented in world space or local space. When set to true
, the glove data is represented in world space. When set to false
, the glove data is represented in local space.
- World Space: Means all the joint positions are represented relative to the world's origin, which in this case is generally the wrist joint of the glove.
- Local Space: The glove data is represented relative previous node. This means that the child, parent relationship is relevant when interpreting the data.
The CoordinateSystemVUH
struct is used to define the coordinate system settings for the glove data. It consists of the following fields:
View: Defines which axis points from the viewer (e.g., X, Y, or Z). It sets the orientation of the coordinate system. This is also known as the forward direction.
AxisView_ZFromViewer
: The Z-axis points away from the viewer.AxisView_YFromViewer
: The Y-axis points away from the viewer.AxisView_XFromViewer
: The X-axis points away from the viewer.AxisView_XToViewer
: The X-axis points towards the viewer.AxisView_YToViewer
: The Y-axis points towards the viewer.AxisView_ZToViewer
: The Z-axis points towards the viewer.
Up: Specifies the system's up-direction (e.g., whether +Z points up).
AxisPolarity_NegativeZ
: The Z-axis points downwards.AxisPolarity_NegativeY
: The Y-axis points downwards.AxisPolarity_NegativeX
: The X-axis points downwards.AxisPolarity_PositiveX
: The X-axis points upwards.AxisPolarity_PositiveY
: The Y-axis points upwards.AxisPolarity_PositiveZ
: The Z-axis points upwards.
Handedness: Determines the direction of the third axis based on the first two (Right-Handed or Left-Handed).
Side_Right
: Right-handed coordinate system (third axis points to the left).Side_Left
: Left-handed coordinate system (third axis points to the right).
Scale: A float value that defines the scale of the coordinate system in meters. The value at 1.0f means the coordinate system is in meters, 0.01f means the coordinate system is in centimeters and so on.
HandMotion
The HandMotion
enum is used to specify the hand motion of the glove data. It's set to HandMotion_None
by default meaning the wrist orientation will be locked.
Usage
To run the ROS2 package, you can use the following command:
Please make sure you have the ROS2 workspace sourced before running the command. For more information on how to source the workspace, please refer to the getting started guide.
License
To make use of the ROS2 package, a MANUS Core license key is required with the correct SDK
feature enabled is required (Core Integrated vs. Core Remote). More information on licenses can be here.