睿尔曼6自由度机械臂ROS驱动包功能拓展之查询指令

news2024/11/14 21:56:21

1:主要环境预览

1:系统:Ubuntu 20.04

2:ROS:noetic

3:对于系统要求需根据相关手册完成机械臂相关依赖安装,能够运行机械臂本身基本功能,    包括 moveit。

4:准备资料,完成功能拓展我们需要依赖以下资料《睿尔曼 6 自由度机械臂 JSON 通信协议v3.5.3》。

2:添加ROS 机械臂驱动包功能说明

机械臂内部有许多的指令,可将其分为三类。

  1. 首先是设置,通俗的理解就是通过一些设置指令改变机械臂的内部参数。
  2. 第二是查询,通过一些查询的方式,使机械臂将本身的参数信息反馈出来。
  3. 第三是反馈,通过对机械臂反馈的指令的解析获取到机械臂的当前配置数据、当前状态或我们在配置后是否成功的反馈。

3:ROS 机械臂驱动包功能添加

3.1 ROS机械臂驱动包查询指令添加

本节我们主要了解一下查询指令是如何添加的,伴随查询指令不可或缺的就是反馈指令的解析,  所以在这里我们将会为大家直接介绍系统性的查询流程,包括查询指令的发布以及查询后收到反馈指令的解析,以手册中的第一个查询指令为例“查询关节最大速度”,下面为主要步骤和操作方式。

1:​​​​​​rm_robot.h 文件中声明订阅函数。

该订阅函数的作用是帮助我们时刻检测是否有查询关节最大速度的话题发出,如果收到该话题, 就会订阅其回调函数,向下发布查询指令。在 rm_robot.h 中添加如下代码声明订阅方。

ros::Subscriber Sub_get_Joint_Max_Speed_Cmd;

实际代码如下:

2:rm_driver.cpp 文件中配置订阅方的相关话题和回调函数。

Sub_get_Joint_Max_Speed_Cmd = nh_.subscribe("/rm_driver/Get_Joint_Max_Speed_ Cmd", 10, Get_Joint_Max_Speed_Callback);

代码中主要参数解析:/rm_driver/Get_Joint_Max_Speed_Cmd 为订阅方所接收的话题。10 为缓存队列Get_Joint_Max_Speed_Callback 为接受到话题后需要执行的回调函数。

3:rm_driver.cpp 文件中构建回调函数实体

void Get_Joint_Max_Speed_Callback(const std_msgs::Empty msg)

{

ROS_INFO("Get_Joint_Max_Speed_Callback!\n"); int res = 0;

res = Get_Joint_Max_Speed(); if(res != 0)

{

ROS_ERROR("Get_Joint_Max_Speed_Callback cmd failed!\n");

}

}

代码解析:其中的核心代码为 res = Get_Joint_Max_Speed();Get_Joint_Max_Speed()函数主要包含了与机械臂通信时的通信函数。通信成功返回 0,失败返回其他错误码,并提示错误信息。

4:​​​​​​​rm_robot.h 文件中构建通信函数

在 rm_robot.h 中添加如下代码构建与机械臂的通信函数。

int Get_Joint_Max_Speed()

{

cJSON *root; char *data;

char buffer[200];

int res; int r = 0;

root = cJSON_CreateObject();

cJSON_AddStringToObject(root, "command", "get_joint_max_speed");

data = cJSON_Print(root); sprintf(buffer, "%s\r\n", data);

res = package_send(Arm_Socket, buffer, strlen(buffer), 0); cJSON_Delete(root);

free(data);

if (res < 0)

{

return 1;

}

return 0;

}

实际代码如下:

        代码解析: 其中用到了 JSON 的数据格式进行数据处理,想要理解的话需要多查看一些 cJSON 的相关资料,这里主要做使用说明。 在这里就需要结合我们的手册进行通信指令的发布了。

功能描述查询关节最大速度
参数说明get_joint_max_speed:查询关节最大速度
命令格式{s:s}
示例{"command":"get_joint_max_speed"}
说明:查询关节最大速度
返回值见表1.3-(1)

        我们在《睿尔曼 6 自由度机械臂 JSON 通信协议 v3.5.3》手册中的查询关节最大速度的相关章 节中可以看到查询关节最大速度的指令示例{"command":"get_joint_max_speed"}。 所以我们在查询时对外发布的指令为:

        cJSON_AddStringToObject(root, "command", "get_joint_max_speed");

        我们在进行其他数据或配置的查询时也需要参照此方法,更改"get_joint_max_speed"为对应 值即可。

        最终通过 package_send(Arm_Socket, buffer, strlen(buffer), 0);函数将处理好的数据发送出 去,到此查询通信完成。

5. 反馈处理代码的添加

        反馈处理实际上我们是在主函数中的 while(1)大循环中完成的。

        在大循环函数中,我们循环检测接收到的数据,在接收到机械臂发来的数据后我们会调用 Parser_Msg(char *msg)函数进行处理,但是在处理接收到的每一个不同的数据时,其处理逻辑也 各有不同,所以我们需要在 Parser_Msg(char *msg)函数体中添加新的处理逻辑。

        在 rm_driver.h 的 Parser_Msg(char *msg)函数中添加如下代码。

json_state = cJSON_GetObjectItem(root, "joint_speed");

if(json_state != NULL)

{

json_state = cJSON_GetObjectItem(root, "state");

if((json_state != NULL) && !strcmp("joint_max_speed",json_state->valuestr ing))

{

res = Parser_Joint_Max_Speed(msg);

if(res == 0)

{

cJSON_Delete(root);

return ARM_JONIT_MAX_SPEED;

}

else

{

cJSON_Delete(root);

return -2;

}

}

}

实际代码如下:

        还需要在 rm_driver.h 的宏定义中,添加获取关节最大速度的宏定义说明,代码如下。

        #define ARM_JONIT_MAX_SPEED 0x20

        实际代码:

        代码解析:

        在该段代码中用到了 cJSON 对读取到的代码的处理,包括获取和值的比较,在这里我们也需 要用到《睿尔曼 6 自由度机械臂 JSON 通信协议 v3.5.3》手册进行数据和通信协议的比对。

        反馈关节最大速度

功能描述反馈所有关节最大速度
参数说明joint_max_speed:反馈关节最大速度
命令格式

{s;s,s:[i,i,i,i,i]}

示例{"state":"joint_max_speed","joint_speed":[30,30,30,30,30,30]}
说明:依次反馈个关节最大转速均为0.03RPM,单位RPM,分辨率:0.001RPM

        如上图所示,反馈关节最大速度的指令格式为{s:s,s:[i,i,i,i,i,i]},其含义为数据类型的简写 {string:string,string:[int,int,int,int,int,int]},可以看到其是由 string 类型和 int 类型的数据组成的, 实际的数据构成为:{"state":"joint_max_speed","joint_speed":[30,30,30,30,30,30]}。

        在实际使用时关节最大速度 string 类型的数据不会改变,主要是 int 类型的数据值会因为我们 的设置发生变化。

        在上面的代码中我们通过对 string 的数据判断是否为对应的我们要处理的数据。

        在确保数据没有问题后我们使用 Parser_Joint_Max_Speed(char *msg)函数进行反馈数据的 解析。

6. 添加反馈数据解析程序

        在 rm_robot.h 文件中添加如下代码,处理反馈程序。

int Parser_Joint_Max_Speed(char *msg)

{

cJSON *root = NULL, *result, *json_sub;

/*解码函数,解析接收到的 msg 信息,解析为 JSON 格式,用以后面进行分析。 */

root = cJSON_Parse(msg);

int data[6];

int i = 0;

root = cJSON_Parse(msg);

result = cJSON_GetObjectItem(root, "joint_speed");

if((result != NULL) && (result->type == cJSON_Array))

{

int size = cJSON_GetArraySize(result);

for(i=0;i<size;i++)

{

json_sub=cJSON_GetArrayitem(result,i);

data[i]=json_sub->valueint;

RM_Joint.joint[i] = data[i];

RM_Joint.joint[i] = RM_Joint.joint[i] / 1000;

}

result = cJSON_GetObjectItem(root, "arm_err");

if (result != NULL && result->type == cJSON_Number)

{

arm_err = result->valueint;

}

cJSON_Delete(root);

return 0;

}

else

{

cJSON_Delete(root);

ROS_ERROR("Parser_Joint_Max_Speed Failed!!!");

return -1;

}

}

        代码解析:

        在如上代码中我们对机械臂传输过来的数组进行了处理,将 JSON 数组中的数据传输到了 RM_Joint 这个结构体对应的数据中,以便于我们在主函数中进行处理。

        这里需要注意的是我们用来传递的数据与真实数据是否对应,如 JSON 传输的数据为 int 类型。

        但是如图所示:

示例{"state":"joint_max_speed","joint_speed":[30,30,30,30,30,30]}
说明:依次反馈个关节最大转速均为0.03RPM,单位RPM,分辨率:0.001RPM

        根据手册说明我们可以知道其传输时放大了 1000 倍,我们需要将其还原为真实值需要使用 float 类型进行保存,在数值保存时需要注意,建议可在 RM_Joint 结构体中新建变量或数组保存。         完成以上操作后我们需要在主函数中完成 while(1)大循环中的数据处理。

7. 在 while(1)大循环中的添加数据处理和发布代码

        在 rm_driver.cpp 中添加如下代码。

case ARM_JONIT_MAX_SPEED:

Joint_Speed_Max.header.stamp = ros::Time::now();

for (i = 0; i < 6; i++)

{

Joint_Speed_Max.max_velocity[i] = RM_Joint.joint[i];

}

Joint_Max_Speed.publish(Joint_Speed_Max); I

nfo_Arm_Err();

break;

实际代码如下:

代码解析:

在如上代码中,我们将数据从 RM_Joint.joint 数组中传递到 Joint_Speed_Max.max_velocity 数组中之后调用 Joint_Max_Speed 发布器进行了发布。在这里面我们还需要进行 Joint_Speed_Max 这个数据的定义和 Joint_Max_Speed 这个发布器的定义。

8. Joint_Max_Speed 发布器添加

        在 rm_driver.h 中添加如下代码。

        ros::Publisher Joint_Max_Speed;

        实际代码如下:

        在 rm_driver.cpp 中添加如下代码。

        Joint_Max_Speed = nh_.advertise("/rm_driver/jo int_max_speed",10);

        实际代码如下:

        代码说明:

        通过以上代码我们添加了关节最大速度话题的发布方,发布方为 Joint_Max_Speed,发布话题 为:/rm_driver/joint_max_speed,我们在查看最大速度的时需要订阅该话题。

        其消息类型为 rm_msgs::Arm_Joint_Speed_Max,此消息类型非 ROS 原本的消息类型,为新 建的消息类型。

9. Arm_Joint_Speed_Max 数据类型添加

        在 rm_msgs 功能包的 msg 文件夹中新建文件 Arm_Joint_Speed_Max.msg,在文件中添加如 下内容。

        std_msgs/Header header

        string[] name

        float64[] max_velocity

        实际代码如下:

        在 CMakeLists.txt 中添加如下代码:

        Arm_Joint_Speed_Max.msg

        实际代码如下:

        对 rm_msgs 功能包进行编译,我们就可以使用该消息类型了。

        在 rm_driver.h 中添加如下代码添加头文件:

        #include <rm_msgs/Arm_Joint_Speed_Max.h>

        实际代码如下:

        在 rm_driver.cpp 中添加如下代码:

rm_msgs::Arm_Joint_Speed_Max Joint_Speed_Max;

Joint_Speed_Max.name.resize(6);

Joint_Speed_Max.max_velocity.resize(6);

Joint_Speed_Max.name[0] = "joint1"; Joint_Speed_Max.name[1] = "joint2";

Joint_Speed_Max.name[2] = "joint3"; Joint_Speed_Max.name[3] = "joint4";

Joint_Speed_Max.name[4] = "joint5"; Joint_Speed_Max.name[5] = "joint6";

        代码如下:

        完成以上操作就可以对 rm_driver 功能包进行编译和运行了。

10. 实现效果

        首先在机器人端打开一个终端运行如下指令进入工作空间进行编译。

        cd ~/catkin_ws

        catkin build rm_driver

        在机器人端新打开一个终端,执行如下指令运行 ROS_MASTER。

        roscore

        在机器人端新打开一个终端,启动 robot_driver 节点。

        rosrun rm_driver rm_driver

        在机器人端新打开一个终端,订阅最大关节速度的发布话题。

        rostopic echo /rm_driver/joint_max_speed

        在机器人端新打开一个终端,发布如下话题,使订阅器调用回调函数,获取机械臂关节最大速 度信息。

        rostopic echo /rm_driver/joint_max_speed

        如下图所示为不同终端的运行指令及提示信息。

        到这里,查询流程基本完毕,这里对基本的查询和反馈流程做了比较详细的说明,供大家学习 了解,更加丰富的内容请参考实际代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1430214.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

星宸科技SSC8826Q 驾驶辅助(ADAS)行车记录仪方案

星宸科技SSC8826Q 驾驶辅助&#xff08;ADAS&#xff09;行车记录仪方案 一、方案描述 SSC8826Q是高度集成的行车记录仪、流媒体后视镜解决方案&#xff0c;主芯片为ARM Cortex A53&#xff0c;dual core&#xff0c;主频高达1.2GHz&#xff0c;集成了64-bit dual-core RISC 处…

向日葵案例解析:无外网接入,医疗设备如何进行远程售后运维

随着医学科学以及生物工程技术的高速发展&#xff0c;医院对于高端医疗设备如MR、CT、B超等高科技成像设备和放射治疗设备的需求激增。医学影像检查作为一种重要的手段&#xff0c;在许多疾病确诊过程中发挥着至关重要的作用。检查结果正确与否&#xff0c;直接影响临床医生对疾…

Java设计模式 – 四大类型

设计模式 – 四大类型 创建型模式结构型模式行为型模式J2EE模式 设计模式&#xff08;Design pattern&#xff09;是重构解决方案 根据书Design Patterns – Elements of Reusable Object-Oriented Software&#xff08;中文译名&#xff1a;设计模式 – 可复用的面向对象软件元…

STM32 HAL NTC(3950 10k)查表法

NTC&#xff08;Negative Temperature Coefficient&#xff09;是指随温度上升电阻呈指数关系减小、具有负温度系数的热敏电阻现象和材料。该材料是利用锰、铜、硅、钴、铁、镍、锌等两种或两种以上的金属氧化物进行充分混合、成型、烧结等工艺而成的半导体陶瓷&#xff0c;可制…

python绘图指南—Bokeh库从基础到高级打造交互式数据可视【第51篇—python:Bokeh库】

文章目录 Bokeh库深度解析&#xff1a;从基础到高级&#xff0c;打造交互式数据可视化安装Bokeh库Bokeh绘图基础基础图形绘制完善图形 实例演示案例&#xff1a;股票走势图 Bokeh库高级功能探索1. 工具栏和交互性2. 高级图形元素3. 数据链接和动态更新 Bokeh库与其他库的整合1.…

C# ONNX使用入门教程

背景 有新入坑的老哥不太了解C# onnx 运行的机理&#xff0c;我这边详细介绍一下&#xff0c;之前直接放官方的样例有点草率了。 准备[python环境] 1、要使用onnx&#xff0c;首先我们就自己生成一个onnx文件&#xff0c;请大家准备一下以下需要的[python]环境 python 版本…

linux 文件查看 head 、 cat 、 less 、tail 、grep

查看文件详细信息 stat 文件 cat 》》适合显示小文件【行数比较少】&#xff0c;如果行数较多&#xff0c;屏幕显示不完整&#xff08;如果虚拟操作&#xff0c;是无法上下键的&#xff0c;或者滚动鼠标的&#xff0c;第三方 xsheel&#xff0c;crt 可以方向键查看&#xf…

MySQL 多表查询

重点&#xff1a; MySQL 的 三种安装方式&#xff1a;包安装&#xff0c;二进制安装&#xff0c;源码编译安装。 MySQL 的 基本使用 MySQL 多实例 DDLcreate alter drop DML insert update delete DQL select 3.5&#xff09;DDL 语句 表&#xff1a;二维关系 设计表&…

【微服务】skywalking自定义链路追踪与日志采集

目录 一、前言 二、自定义链路追踪简介 2.1 自定义链路追踪应用场景 2.2 链路追踪几个关键概念 三、skywalking 自定义链路追踪实现 3.1 环境准备 3.2 集成过程 3.2.1 导入核心依赖 3.2.2 几个常用注解 3.2.3 方法集成 3.2.4 上报追踪信息 四、skywalking 自定义日志…

Spring速成(二)

Spring速成&#xff08;二&#xff09; 掌握IOC/DI配置管理第三方bean掌握IOC/DI的注解开发掌握IOC/DI注解管理第三方bean完成Spring与Mybatis及Junit的整合开发 1&#xff0c;IOC/DI配置管理第三方bean 1.1 案例:数据源对象管理 1.1.1 环境准备 学习之前&#xff0c;先来准…

STM32标准库——(9)TIM编码器接口

1.编码器接口简介 Encoder Interface 编码器接口编码器接口可接收增量&#xff08;正交&#xff09;编码器的信号&#xff0c;根据编码器旋转产生的正交信号脉冲&#xff0c;自动控制CNT自增或自减&#xff0c;从而指示编码器的位置、旋转方向和旋转速度每个高级定时器和通用定…

异步编程Completablefuture使用详解----进阶篇

JDK版本&#xff1a;jdk17 IDEA版本&#xff1a;IntelliJ IDEA 2022.1.3 文章目录 前言一、异步任务的交互1.1 applyToEither1.2 acceptEither1.3 runAfterEither 二、get() 和 join() 区别三、ParallelStream VS CompletableFuture3.1 使用串行流执行并统计总耗时3.2 使用并行…

单元/集成测试服务

服务概述 单元/集成测试旨在证明被测软件实现其单元/架构设计规范、证明被测软件不包含非预期功能。经纬恒润测试团队拥有丰富的研发经验、严格的流程管控&#xff0c;依据ISO26262/ASPICE等开展符合要求的单元测试/集成测试工作。 在ISO 26262 - part6 部分产品开发&#xff…

荣耀手机如何录屏?在线分享3个录屏方法

荣耀手机如何录屏&#xff1f;荣耀手机录屏是一项非常实用的功能&#xff0c;它可以帮助我们轻松记录手机屏幕上的内容&#xff0c;无论是游戏攻略、教育学习还是工作演示&#xff0c;都能够方便地进行录制。通过录屏&#xff0c;我们可以随时随地记录和分享自己的操作和见解。…

C++ 动态规划 线性DP 最长上升子序列

给定一个长度为 N 的数列&#xff0c;求数值严格单调递增的子序列的长度最长是多少。 输入格式 第一行包含整数 N 。 第二行包含 N 个整数&#xff0c;表示完整序列。 输出格式 输出一个整数&#xff0c;表示最大长度。 数据范围 1≤N≤1000 &#xff0c; −109≤数列中的数…

学成在线: 新增/修改课程计划

新增/修改课程计划(同接口) 界面原型 第一步: 在课程计划界面,点击添加章新增第一级课程计划,点击添加小节可以向某个第一级课程计划下添加小节 新增章/节成功后会自动发起请求刷新课程计划列表并且把新增的课程计划信息添加到数据库当中,新增的课程计划自动排序到最后 第二…

2024年第三届能源与环境工程国际会议(CFEEE 2024) | Ei&Scopus双检索

会议简介 Brief Introduction 2024年第三届能源与环境工程国际会议(CFEEE 2024) 会议时间&#xff1a;2024年12月12日-14日 召开地点&#xff1a;澳大利亚凯恩斯 大会官网&#xff1a;CFEEE 2024-2024 International Conference on Frontiers of Energy and Environment Engine…

【python】python爱心代码

一、实现效果&#xff1a; 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 二、准备工作 &#xff08;1)、导入必要的模块&#xff1a; 代码首先导入了需要使用的模块&#xff1a;requests、lxml和csv。 import requests from lxml import etree import csv 如果出现…

不同状态角 θz 下的 K2eff 和 Kav 计算结果

不同状态角 θ z 下的 K 2 eff 和 K av 计算结果 clear clc close all syms theta for theta_z[pi/5,pi/3,pi/2,2*pi/3,4*pi/5,pi] % theta_zdtheta_z*180/pi theta_1-theta_z/2; theta_2theta_z/2; fthetacos(theta); ftheta2cos(theta)^2; Keff2int(ftheta2,theta_1,…

png,jpg,bmp等格式图像转.npy文件(附代码)

目录 一、npy文件二、代码三、转后效果 一、npy文件 .npy 文件是 NumPy 库用于存储数组的二进制文件格式。这种文件可以存储一个或多个 NumPy 数组对象。.npy 文件在保存和加载 NumPy 数组时非常有用&#xff0c;因为它们可以用于在磁盘上高效地存储数据&#xff0c;并且在加载…