MoveIt 控制自己的真实机械臂【2】——编写 action server 端代码
完成了 MoveIt 这边 action client 的基本配置,MoveIt 理论上可以将规划好的 trajectory 以 action 的形式发布出来了,浅浅尝试一下,在 terminal 中运行 roslaunch xmate7_moveit_config_new demo.launch
报错提示他在等待 xmate_arm_controller/follow_joint_trajectory 这个 action sever 的到来,显然,他等的好辛苦,却还是没有等来所期待的人,最终遗憾地告诉大家,以 xmate_arm_controller/follow_joint_trajectory 为 action 名称的 action client 端没有被连接。
此时,rostopic list 一下:
hjs@hjs:~/new_xmate7pro_ws$ rostopic list
/attached_collision_object
/collision_object
/execute_trajectory/cancel
/execute_trajectory/feedback
/execute_trajectory/goal
/execute_trajectory/result
/execute_trajectory/status
/head_mount_kinect/depth_registered/points
/joint_states
/move_group/cancel
/move_group/display_contacts
/move_group/display_cost_sources
/move_group/display_grasp_markers
/move_group/display_planned_path
/move_group/feedback
/move_group/filtered_cloud
/move_group/goal
/move_group/monitored_planning_scene
/move_group/motion_plan_request
/move_group/ompl/parameter_descriptions
/move_group/ompl/parameter_updates
/move_group/plan_execution/parameter_descriptions
/move_group/plan_execution/parameter_updates
/move_group/planning_scene_monitor/parameter_descriptions
/move_group/planning_scene_monitor/parameter_updates
/move_group/result
/move_group/sense_for_plan/parameter_descriptions
/move_group/sense_for_plan/parameter_updates
/move_group/status
/move_group/trajectory_execution/parameter_descriptions
/move_group/trajectory_execution/parameter_updates
/pickup/cancel
/pickup/feedback
/pickup/goal
/pickup/result
/pickup/status
/place/cancel
/place/feedback
/place/goal
/place/result
/place/status
/planning_scene
/planning_scene_world
/real_controller_joint_states
/recognized_object_array
/rosout
/rosout_agg
/rviz_hjs_12716_2381460729014530723/motionplanning_planning_scene_monitor/parameter_descriptions
/rviz_hjs_12716_2381460729014530723/motionplanning_planning_scene_monitor/parameter_updates
/rviz_moveit_motion_planning_display/robot_interaction_interactive_marker_topic/feedback
/rviz_moveit_motion_planning_display/robot_interaction_interactive_marker_topic/update
/rviz_moveit_motion_planning_display/robot_interaction_interactive_marker_topic/update_full
/tf
/tf_static
/trajectory_execution_event
发现根本没有 xmate_arm_controller/follow_joint_trajectory 这个名称的 action 发布出来。
想想也能理解,MoveIt 端的 action client 苦苦等了好久的另一半(action server),action server 却终究没有出现和给出回应,那么action client自然也就,没有必要再将自己的爱意(xmate_arm_controller/follow_joint_trajectory) 表达出来了。
言归正传,之前在 Gazebo 中虚拟仿真的时候,是 Gazebo 的 ros_control 插件充当了 action server 的角色,让 MoveIt 端的 client 和 Gazebo 端的 server 建立了 action 通信连接;那么现在,针对真实机械臂,没有人再充当 action server 的角色了,自然也就没有 follow_joint_trajectory 发布出来,所以下一步要做的就是自己编写一个 Movet 端的 action client 所倾慕的 action server ,并为它们牵线(配置接口),介绍它们认识(建立连接),进而实现 follow_joint_trajectory 的发布和接收。
关于 ROS action 相关知识的学习自行补上,我编写的 action server 节点如下:
# include <ros/ros.h>
# include <actionlib/server/simple_action_server.h>
# include <control_msgs/FollowJointTrajectoryAction.h>
# include <std_msgs/Float32MultiArray.h>
# include <iostream>
# include <moveit_msgs/RobotTrajectory.h>using namespace std;
// 重命名类型为 Server
typedef actionlib::SimpleActionServer<control_msgs::FollowJointTrajectoryAction> Server;// 用于存储 moveit 发送出来的轨迹数据
moveit_msgs::RobotTrajectory moveit_tra;void execute_callback(const control_msgs::FollowJointTrajectoryGoalConstPtr& goalPtr, Server* moveit_server)
{// 1、解析提交的目标值int n_joints = goalPtr->trajectory.joint_names.size();int n_tra_Points = goalPtr->trajectory.points.size();moveit_tra.joint_trajectory.header.frame_id = goalPtr->trajectory.header.frame_id;moveit_tra.joint_trajectory.joint_names = goalPtr->trajectory.joint_names;moveit_tra.joint_trajectory.points.resize(n_tra_Points);for(int i=0; i<n_tra_Points; i++) // 遍历每组路点{moveit_tra.joint_trajectory.points[i].positions.resize(n_joints);moveit_tra.joint_trajectory.points[i].velocities.resize(n_joints);moveit_tra.joint_trajectory.points[i].accelerations.resize(n_joints);moveit_tra.joint_trajectory.points[i].time_from_start = goalPtr->trajectory.points[i].time_from_start;for(int j=0;j<n_joints; j++) // 遍历每组路点中的每个关节数据{moveit_tra.joint_trajectory.points[i].positions[j] = goalPtr->trajectory.points[i].positions[j];moveit_tra.joint_trajectory.points[i].velocities[j] = goalPtr->trajectory.points[i].velocities[j];moveit_tra.joint_trajectory.points[i].accelerations[j] = goalPtr->trajectory.points[i].accelerations[j];}}cout << "The trajectory data is:" << "********************************************" << endl;cout << moveit_tra;cout << "********************************************" << "The trajectory data is finished printing." << endl;ROS_INFO("The number of joints is %d.",n_joints);ROS_INFO("The waypoints number of the trajectory is %d.",n_tra_Points);ROS_INFO("Receive trajectory successfully");moveit_server->setSucceeded();
}int main(int argc, char *argv[])
{ros::init(argc,argv,"moveit_action_server");ros::NodeHandle nh;// 创建 action 对象(NodeHandle,话题名称,回调函数解析传入的目标值,服务器是否自启动)Server moveit_server(nh,"xmate_arm_controller/follow_joint_trajectory", boost::bind(&execute_callback, _1, &moveit_server), false);// 手动启动服务器moveit_server.start();ros::spin();return 0;
}
该节点实现的功能就是:
启动了一个 xmate_arm_controller/follow_joint_trajectory 名称的 action server,而正是这个名称的 action,才是 MoveIt 端的 action client 所喜欢的,具体原因见上一篇博客5、创建 ros_controllers.yaml 文件;
在启动的 action server 回调函数中解析了 MoveIt 规划的轨迹数据,并把该轨迹数据存储到了 moveit_msgs::RobotTrajectory 类型的变量 moveit_tra 中。
验证:
terminal 1:roscore;
terminal 2: 启动 action server 节点,rosrun xmate7_demo moveit_action_server;
此时 rostopic list 结果:
terminal 3: 启动 action client 节点,roslaunch xmate7_moveit_config_new demo.launch;
此时,终端不会报错,而且提示
[ INFO] [1658643437.543320231]: Added FollowJointTrajectory controller for xmate_arm_controller
将 Rviz 中的拖动球拖动,点击 Plan & Excute 会发现 terminal 2会按照我所写代码打印出 MoveIt 的轨迹数据。
可见,MoveIt 规划的轨迹,让机械臂从 home 姿态运动到目标姿态生成了 33 个路点,对应每个路点的位置、速度、加速度以及时间戳也都解析到了 moveit_tra 这个变量中了,以上验证表明我们自己实现的 action server 代码实现了和 MoveIt 端 action client 的 connect,并且拿到了 MoveIt 规划出来的轨迹数据。顺其自然,为了实现用 MoveIt 控制自己的真实机械臂的宏图大业,当然下一步就是将我们拿到的 trajectory 数据作为指令数据发送给真实的机械臂去执行,这将在下一篇文章中描述。
另外,上述示例 action server 代码实现方式比较简单,还可以将 action server 封装成类的形式,在类中编写回调函数,丰富 action 机制的使用接口,在类中初始化 action 对象可参照action 官网
相关文章:
MoveIt 控制自己的真实机械臂【2】——编写 action server 端代码
完成了 MoveIt 这边 action client 的基本配置,MoveIt 理论上可以将规划好的 trajectory 以 action 的形式发布出来了,浅浅尝试一下,在 terminal 中运行 roslaunch xmate7_moveit_config_new demo.launch 报错提示他在等待 xmate_arm_control…...
C#制作学生管理系统
定义学生类 定义一个简单的类来表示学生,包括学号、姓名、性别、年龄、电话、地址。再给其添加一个方法利于后续添加方法查看学生信息。 //定义学生类 public class student {public int ID { get; set; }//开放读写权限public string Name { get; set; }public i…...
python Pandas合并(单元格、sheet、excel )
安装 Pandas 和 openpyxl 首先,确保已经安装了 Pandas 和 openpyxl。可以通过 pip 安装: pip install pandas openpyxl 创建 DataFrame import pandas as pd # 创建 DataFrame df1 pd.DataFrame({ 姓名: [张三, 李四, 王五], 年龄: [25, 30, 35]…...
OJ在线编程常见输入输出练习【JavaScript】
(注:本文是对【JavaScript Node 】 ACM模式,常见输入输出练习相关内容的介绍!!!) 牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ 一、ACM模式下的编辑页面 二、ACM模式下&a…...
新能源汽车空调系统:绿色出行的舒适保障
在新能源汽车迅速发展的今天,空调系统作为提升驾乘舒适度的重要组成部分,发挥着不可或缺的作用。新能源汽车空调系统主要由压缩机、冷凝器、节流装置和蒸发器四大件组成,它们协同工作,为车内提供适宜的温度和湿度环境。 一、压缩…...
Date工具类详细汇总-Date日期相关方法
# 1024程序员节 | 征文 # 目录 简介 Date工具类单元测试 Date工具类 简介 本文章是个人总结实际工作中常用到的Date工具类,主要包含Java-jdk8以下版本的Date相关使用方法,可以方便的在工作中灵活的应用,在个人工作期间频繁使用这些时间的格…...
TMUX1308PWR规格书 数据手册 具有注入电流控制功能的 5V 双向 8:1单通道和 4:1 双通道多路复用器芯片
TMUX1308 和 TMUX1309 为通用互补金属氧化物半导体 (CMOS) 多路复用器 (MUX)。TMUX1308 是 8:1单通道(单端)多路复用器,而 TMUX1309 是 4:1 双通道(差分)多路复用器。这些器件可在源极 (Sx) 和漏极 (Dx) 引脚上支持从 …...
证件照怎么换底色?简单又快速!不看后悔
一、引言 证件照在我们的生活中有着广泛的应用,无论是求职、考试还是办理各种证件,都需要用到不同底色的证件照。传统的换底色方法往往比较复杂,需要一定的专业技能和软件操作经验。但是现在,有了更简单快捷的方法,让你…...
Rust 基础语法与常用特性
Rust 跨界:全面掌握跨平台应用开发 第一章:快速上手 Rust 1.2 基础语法与常用特性 1.2.1 数据类型与控制流 数据类型 Rust 提供了丰富的内置数据类型,主要分为标量类型和复合类型。 标量类型 标量类型表示单一的值,Rust 中…...
一、开发环境的搭建
环境搭建步骤: 下载软件安装软件运行软件 其他: Visual studio 安装包文件:https://www.alipan.com/s/nd5RgzD4e3b 下载软件 在浏览器中搜索Visual studio,选择如图的选项 点击该区域,进入该页面,【或…...
Docker:存储原理
Docker:存储原理 镜像联合文件系统overlay镜像存储结构容器存储结构 存储卷绑定挂载存储卷结构 镜像 联合文件系统 联合文件系统Union File System是一种分层,轻量且高效的文件系统。其将整个文件系统分为多个层,层与层之间进行覆盖&#x…...
ts:数组的常用方法(push、pop、shift、unshift、splice、slice)
前端css中filter的使用 一、主要内容说明二、例子(一)、push方法(尾添加)1.源码1 (push方法)2.源码1运行效果 (二)、pop方法(尾删除)1.源码2(pop方…...
物联网网关确保设备安全
物联网(IoT)网关在确保设备安全方面扮演着至关重要的角色。 作为连接物联网设备和云端或企业系统的中介,物联网网关可以实施多种安全措施来保护设备和数据。 是物联网网关确保设备安全的关键方法: 1. 设备认证和授权 认证&…...
Vue学习笔记(五)
Class绑定 数据绑定的一个常见需求场景式操纵元素的CSS class列表,因为class是attribute,我们可以和其他attribute一样使用v-bind将它们和动态的字符串绑定。但是,在处理比较复杂的绑定时,通过拼接生成字符串是麻烦且易出错的。因此…...
Nestjs返回格式小结
在 NestJS 中,除了 text/event-stream(用于 Server-Sent Events)之外,还有多种格式的返回方式,具体取决于你的应用需求。以下是一些常见的返回格式及其示例: 1. JSON 格式 Get(json) getJsonResponse(Res…...
【力扣刷题实战】相同的树
大家好,我是小卡皮巴拉 文章目录 目录 力扣题目: 相同的树 题目描述 示例 1: 示例 2: 示例 3: 解题思路 题目理解 算法选择 具体思路 解题要点 完整代码(C语言) 兄弟们共勉 &#…...
Golang | Leetcode Golang题解之第515题在每个树行中找最大值
题目: 题解: func largestValues(root *TreeNode) (ans []int) {if root nil {return}q : []*TreeNode{root}for len(q) > 0 {maxVal : math.MinInt32tmp : qq nilfor _, node : range tmp {maxVal max(maxVal, node.Val)if node.Left ! nil {q …...
Zookeeper 对于 Kafka 的作用是什么?
大家好,我是锋哥。今天分享关于【Zookeeper 对于 Kafka 的作用是什么?】面试题?希望对大家有帮助; Zookeeper 对于 Kafka 的作用是什么? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 ZooKeeper 在 Kafka…...
Thread类及线程的核心操作
一. Thread类的常见构造方法 1. Thread() Thread类无参的构造方法, 用于创建Thread类的实例对象. 2. Thread(String name) 带一个参数的Thread类构造方法, 创建一个线程对象, 并给其命名. [注]: 如果不专门给线程命名, 那么线程默认的名字就是Thread-0, Thread-1, Thread-…...
算法|牛客网华为机试11-20C++
牛客网华为机试 上篇:算法|牛客网华为机试1-10C 文章目录 HJ11 数字颠倒HJ12 字符串反转HJ13 句子逆序HJ14 字符串排序HJ15 求int型正整数在内存中存储时1的个数HJ16 购物单HJ17 坐标移动HJ18 识别有效的IP地址和掩码并进行分类统计HJ19 简单错误记录HJ20 密码验证…...
OpenAI低调发布多智能体工具Swarm:让多个智能体协同工作!
大家好,我是木易,一个持续关注AI领域的互联网技术产品经理,国内Top2本科,美国Top10 CS研究生,MBA。我坚信AI是普通人变强的“外挂”,专注于分享AI全维度知识,包括但不限于AI科普,AI工…...
性能之光 年度电竞性能旗舰iQOO 13发布
2024年10月30日,被定义为“性能之光”的年度电竞性能旗舰——iQOO 13正式发布,售价3999元起。iQOO 13作为iQOO 品牌在性能上的又一次深入探索,它像是一束光,引领行业不断拉高性能上限,让用户看到更多的可能性。 iQOO …...
如何避免因不熟悉数据保护法规而受损
在当今数字化时代,数据保护法规的遵守对于企业至关重要。不熟悉新的数据保护法规会导致法律风险增加、财务损失、声誉受损、客户信任下降等多方面的负面影响。其中,法律风险增加尤为严重,因为不符合规定可能引发高额罚款和法律诉讼。企业若未…...
LLaMA Factory 核心原理讲解
大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于大模型算法的研究与应用。曾担任百度千帆大模型比赛、BPAA算法大赛评委,编写微软OpenAI考试认证指导手册。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。授权多项发明专利。对机器学…...
Java题集练习5
Java题集练习5(集合) 1.三种集合差别,集合类都是什么,数据结构是什么,都什么时候用 三者关系 Set集合 Set接口是Collection接口的一个子接口是无序的,set中不包含重复的元素,也就是说set中不…...
操作系统学习笔记-2.3哲学家和管程问题
哲学家问题 问题描述 假设有五位哲学家围坐在一张圆桌旁,每位哲学家面前放有一盘意大利面,他们各自间隔放置一根叉子。哲学家的行为分为“思考”和“进餐”两种状态。为了进餐,哲学家需要同时拿起左手边和右手边的两根叉子。用餐结束后&…...
2023年信息安全工程师摸底测试卷
目录 1.密码算法 2.等级保护 3.密码学 4.安全评估 5.网络安全控制技术 6.恶意代码 7.身份认证 8.资产管理 9.密码分类 10.被动攻击 11.商用密码服务编辑 12.超文本传输协议 13.数字水印技术 14.信息系统安全设计 15.重放攻击 16.信息资产保护 17.身份认证 …...
ReactOS系统中平衡二叉树。给定地址超导其所属区块MmFindRegion()
系列文章目录 PMM_REGION NTAPI MmFindRegion( PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address, PVOID* RegionBaseAddress ); 宏函数 //给定地址找到其中所属区块 #define CONTAINING_RECORD(address,type,field) ((type FAR *\(PCHAR)(address)-(PCHAR)(&…...
基于TESSY的单元测试与分类树方法深入解析
在现代软件开发中,单元测试是确保软件质量和可靠性的关键步骤之一。特别是对于嵌入式软件,由于其应用环境的特殊性和高安全性要求,单元测试显得尤为重要。本文将基于《TESSY 用户手册》的内容,详细介绍如何使用TESSY 进行单元测试,并深入探讨分类树方法(Classification T…...
整理了一些大模型的课程,非常详细,大模型零基础入门到精通,收藏我这一篇就够了
目前有多个科普类的大模型课程,这些课程涵盖了从基础理论到实际应用的各个方面。以下是一些主要的科普类大模型课程:复旦大学“大模型开发与赋能”专题讲习班:由复旦大学计算机学院邱锡鹏教授带来的《大模型科普讲解》课程,通过深…...
芜湖营销型网站建设/免费html网站模板
Python笔记-爬取Boss直聘的招聘信息 最近迷上了爬虫,爬取招聘信息,存在MongoDB上 代码思路和上一篇爬取酷狗TOP500差不多,但是在使用CSS选择器的时候,有两组信息是连在一起,所以使用正则来获取 本来使用串行爬取完美…...
美术馆网站建设总体要求/说到很多seo人员都转行了
关于切片 按照我的理解的话,切片相当于是一个循环,语法就是for...in 列表或tuple名称,然后逐个遍历出来 但是切片可以根据自己想要的数据进行取舍 首先定义一个列表 Numberlist(range(100)) #0-99的数字如若想取出前20个数字的话,…...
专业建站开发/网络营销培训课程
注:以下内容适用于WPF、C#编码。 最近对异步编程产生了较大的兴趣,所以写出来和感兴趣的朋友一起分享! 1、关于Dispatcher 调度类: 提供用于管理线程的工作项队列的服务。 通常,WPF 应用程序从两个线程开始&#…...
工信部查网站备案/app下载推广
取(m堆)石子游戏 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1263 Accepted Submission(s): 754 Problem Descriptionm 堆石子,两人轮流取.只能在1堆中取.取完者胜.先取者负输出No.先取者胜输出Yes,然后输出…...
网站建设和网络推广是干嘛/电商网站对比
Springboot与jdbc&&数据源Druid 目录结构如下: 使用Maven构建的项目,我们需要在pom文件中加入mysql驱动的依赖、SpringBoot-jdbc的依赖、druid的依赖还有两个基本的SpringBoot依赖:spring-boot-starter-web和spring-boot-starter-…...
北京又有疫情了吗今天/seo网站编辑优化招聘
在SVM中,将约束问题转化成非约束问题采用到了拉格朗日乘子法。这个文章就讲一下拉格朗日乘子法与KKT约束是怎么回事。本人不是数学科班出身,但是也只能硬着头皮讲一讲了。从零理解现在我们要解决这样一个问题:这个函数距离原点最近的距离是多…...