Skip to content

Multi-Robot Arm Control Operations Demo

1. Project introduction

This project, via the RealMan C++ development package, completes multi-robotic arm connection, robotic arm version acquisition, API version acquisition, movej motion, moveL motion, and disconnection.

2. Code structure

RMDemo_DoubleControl

├── build/                       <- Output directory generated by CMake build (e.g., Makefile, build files, etc.)
├── data/
│   └── robot_log.txt            <- Directory for data files such as logs and trajectory files (generated during execution)
├── Robotic_Arm/                 <- RealMan robotic arm secondary development package
│   ├── include/
│   │   ├── rm_define.h          <- Robotic arm definitions
│   │   └── rm_interface.h       <- Robotic arm API interface header file
│   └── lib/
│       ├── api_cpp.dll          <- Windows API library
│       ├── api_cpp.lib          <- Windows API library
│       └── libapi_cpp.so        <- Linux x86 API library
├── src/                         <- Source file storage directory
│   ├── main.c                   <- Source file for main functions
├── run.bat                      <- Quick run script, bat script for Windows
├── run.sh                       <- Quick run script, shell script for Linux
├── CMakeLists.txt               <- Top-level CMake configuration file of the project
├── README.md                    <- Detailed documentation for the sample project

3. Project download

Download RM_API2 locally via the link: development package download. Then, navigate to the RM_API2\Demo\RMDemo_Cpp directory, where you will find RMDemo_DoubleControl.

4. Environment configuration

  • Operating System: Ubuntu 24.04 or higher version.

  • Compiler: GCC 13.3.0 or higher version (or any other compatible C compiler).

  • Dependent Libraries:

    • CMake 3.28.3 or higher version.
    • RMAPI library (included in the Robotic_Arm/lib directory).
  • Header File Dependencies:

#include <stdio.h>
#include <iostream>
#include <thread>
#include <string.h>
#include "rm_service.h"
#ifdef _WIN32
#include <windows.h>
#define SLEEP_MS(ms) Sleep(ms)
#define SLEEP_S(s) Sleep((s) * 1000)
#else
#include <unistd.h>
#define SLEEP_MS(ms) usleep((ms) * 1000)
#define SLEEP_S(s) sleep(s)
#endif

5. Notes

  1. This demo takes the RM65-B robotic arm as an example. Please modify the data in the code according to the actual situation.
  2. Pay attention to the limit when setting start_pose and set reasonable values
start_pose = { {0.3f, 0.1f, 0.4f}, {0.0f, 0.0f, 0.0f, 0.0f}, {3.141f, 0.0f, 0.0f} };`

6. User guide

6.1 Set the IP address and port number

const char* ip1 = "192.168.1.18";
int port1 = 8080;
const char* ip2 = "192.168.1.21";
int port2 = 8080;

6.2 Start threads (pass task_id=1 and task_id=2 respectively)

std::thread arm1_thread(arm_task, ip1, port1, 1);  // Robotic arm1 executes the first set of actions
std::thread arm2_thread(arm_task, ip2, port2, 2);  // Robotic arm2 executes the second set of actions

6.3 Define parameters for two sets of actions

First set of action parameters

float temp_joint1[ARM_DOF] = { 0.0f, 0.5f, 0.3f, 0.0f, 0.2f, 0.0f, 0.1f };
memcpy(joint_angles, temp_joint1, sizeof(temp_joint1));
start_pose = { {0.3f, 0.1f, 0.4f}, {0.0f, 0.0f, 0.0f, 0.0f}, {3.141f, 0.0f, 0.0f} };
target_pose = { {0.2f, 0.1f, 0.3f}, {0.0f, 0.0f, 0.0f}, {3.141f, 0.0f, 0.0f} };
loop_count = 2;
move_speed = 20;

Second set of action parameters

float temp_joint2[ARM_DOF] = { 0.2f, -0.3f, 0.1f, 0.5f, -0.2f, 0.3f, 0.0f };
memcpy(joint_angles, temp_joint2, sizeof(temp_joint2));
start_pose = { {0.3f, 0.1f, 0.4f}, {0.0f, 0.0f, 0.0f, 0.0f}, {3.141f, 0.0f, 0.0f} };
target_pose = { {0.25f, -0.1f, 0.35f}, {0.0f, 0.0f, 0.0f}, {3.141f, 0.0f, 0.0f} };
loop_count = 3;
move_speed = 15;

6.4 Start threads (pass task_id=1 and task_id=2 respectively)

if (task_id == 1) {
    // First set of actions:
    result = arm_service.rm_movel(robot_handle, target_pose, move_speed + 10, 0, 0, 1);
}
else {
    // Second set of actions:
    result = arm_service.rm_movel(robot_handle, target_pose, move_speed + 10, 0, 0, 1);
}

6.5 Disconnect from both robotic arms

result = arm_service.rm_delete_robot_arm(robot_handle);
check_result(result, "Failed to disconnect the robot arm");
printf("Task %d completed for %s:%d\n", task_id, ip, port);

7. License information

  • This project is subject to the MIT license.