目录

  • 一、什么是动作通讯模型
  • 二、创建工作区间
    • 1、创建功能包
    • 2、编译功能包
  • 三、动作编程
    • 1、定义action文件
    • 2、创建.cpp文件
    • 3、编译及运行
  • 四、分布式通讯
    • 1、主机
    • 2、从机
    • 3、运行结果
  • 五、总结
  • 六、参考资料

一、什么是动作通讯模型

二、创建工作区间

1、创建功能包

mkdir -p ~/catkin_ws/src
cd catkin_ws/src/
catkin_create_pkg learn_action std_msgs rospy roscpp

2、编译功能包

cd ~/catkin_ws
catkin_make
source ~/catkin_ws/devel/setup.bash

三、动作编程

1、定义action文件

在learn_action文件下创建action文件

在action文件下创建TurtleMove.action文件,并在TurtleMove.action文件内输入代码:

# Define the goal
float64 turtle_target_x
# Specify Turtle's target position
float64 turtle_target_y
float64 turtle_target_theta
---
# Define the result
float64 turtle_final_x
float64 turtle_final_y
float64 turtle_final_theta
---
# Define a feedback message
float64 present_turtle_x
float64 present_turtle_y
float64 present_turtle_theta

2、创建.cpp文件

在learn_action的src文件夹下,创建TurtleMove_server.cpp文件和TurtleMove_client.cpp文件

1)TurtleMove_server.cpp文件

  /*      此程序通过通过动作编程实现由client发布一个目标位置    然后控制Turtle运动到目标位置的过程  */
#include <ros/ros.h> #include <actionlib/server/simple_action_server.h>
#include "learn_action/TurtleMoveAction.h"
#include <turtlesim/Pose.h>
#include <turtlesim/Spawn.h>
#include <geometry_msgs/Twist.h>
typedef actionlib::SimpleActionServer<learn_action::TurtleMoveAction> Server;
struct Myturtle
{     float x;     float y;     float theta; }turtle_original_pose,turtle_target_pose;   ros::Publisher turtle_vel;  void posecallback(const turtlesim::PoseConstPtr& msg)  {    ROS_INFO("Turtle1_position:(%f,%f,%f)",msg->x,msg->y,msg->theta);   turtle_original_pose.x=msg->x;    turtle_original_pose.y=msg->y;   turtle_original_pose.theta=msg->theta;  }   // 收到action的goal后调用该回调函数 void execute(const learn_action::TurtleMoveGoalConstPtr& goal, Server* as) {     learn_action::TurtleMoveFeedback feedback;       ROS_INFO("TurtleMove is working.");     turtle_target_pose.x=goal->turtle_target_x;     turtle_target_pose.y=goal->turtle_target_y;      turtle_target_pose.theta=goal->turtle_target_theta;          geometry_msgs::Twist vel_msgs;     float break_flag;          while(1)     {           ros::Rate r(10);                  vel_msgs.angular.z = 4.0 * (atan2(turtle_target_pose.y-turtle_original_pose.y,                                    turtle_target_pose.x-turtle_original_pose.x)-turtle_original_pose.theta);         vel_msgs.linear.x = 0.5 * sqrt(pow(turtle_target_pose.x-turtle_original_pose.x, 2) +                                       pow(turtle_target_pose.y-turtle_original_pose.y, 2));          break_flag=sqrt(pow(turtle_target_pose.x-turtle_original_pose.x, 2) +                                         pow(turtle_target_pose.y-turtle_original_pose.y, 2));         turtle_vel.publish(vel_msgs);feedback.present_turtle_x=turtle_original_pose.x;         feedback.present_turtle_y=turtle_original_pose.y;         feedback.present_turtle_theta=turtle_original_pose.theta;         as->publishFeedback(feedback);         ROS_INFO("break_flag=%f",break_flag);         if(break_flag<0.1) break;         r.sleep();     }         // 当action完成后,向客户端返回结果         ROS_INFO("TurtleMove is finished.");         as->setSucceeded();
}
int main(int argc, char** argv)
{     ros::init(argc, argv, "TurtleMove_server");     ros::NodeHandle n,turtle_node;     ros::Subscriber sub =turtle_node.subscribe("turtle1/pose",10,&posecallback);//订阅小乌龟的位置信息     turtle_vel = turtle_node.advertise<geometry_msgs::Twist>("turtle1/cmd_vel",10);//发布控制小乌龟运动的速度     // 定义一个服务器         Server server(n, "TurtleMove", boost::bind(&execute, _1, &server), false);        // 服务器开始运行         server.start();         ROS_INFO("server has started.");     ros::spin();       return 0;
}

2)TurtleMove_client.cpp文件

#include <actionlib/client/simple_action_client.h>
#include "learn_action/TurtleMoveAction.h"
#include <turtlesim/Pose.h>
#include <turtlesim/Spawn.h>
#include <geometry_msgs/Twist.h>
typedef actionlib::SimpleActionClient<learn_action::TurtleMoveAction> Client;
struct Myturtle
{     float x;     float y;   float theta;
}turtle_present_pose;
// 当action完成后会调用该回调函数一次
void doneCb(const actionlib::SimpleClientGoalState& state,         const learn_action::TurtleMoveResultConstPtr& result)
{     ROS_INFO("Yay! The TurtleMove is finished!");     ros::shutdown();
}
// 当action激活后会调用该回调函数一次
void activeCb()
{     ROS_INFO("Goal just went active");
}
// 收到feedback后调用该回调函数
void feedbackCb(const learn_action::TurtleMoveFeedbackConstPtr& feedback)
{     ROS_INFO(" present_pose : %f  %f  %f", feedback->present_turtle_x,                    feedback->present_turtle_y,feedback->present_turtle_theta);
}
int main(int argc, char** argv)
{     ros::init(argc, argv, "TurtleMove_client");       // 定义一个客户端     Client client("TurtleMove", true);       // 等待服务器端     ROS_INFO("Waiting for action server to start.");     client.waitForServer();     ROS_INFO("Action server started, sending goal.");      // 创建一个action的goal     learn_action::TurtleMoveGoal goal;    goal.turtle_target_x = 1;     goal.turtle_target_y = 1;     goal.turtle_target_theta = 0;       // 发送action的goal给服务器端,并且设置回调函数     client.sendGoal(goal,  &doneCb, &activeCb, &feedbackCb);       ros::spin();      return 0;
}

3)修改package.xml文件如图

<build_depend>message_generation</build_depend>
<build_depend>actionlib</build_depend>
<build_depend>actionlib_msgs</build_depend>
<exec_depend>message_runtime</exec_depend>
<exec_depend>actionlib</exec_depend>
<exec_depend>actionlib_msgs</exec_depend>

4)修改 ~/catkin_ws/src/learn_action/CMakeLists.txt

按如下图片作修改:





最后在末尾添加:
代码如下:

add_executable(TurtleMove_client src/TurtleMove_client.cpp)
target_link_libraries(TurtleMove_client ${catkin_LIBRARIES})
add_dependencies(TurtleMove_client ${PROJECT_NAME}_gencpp)  add_executable(TurtleMove_server src/TurtleMove_server.cpp)
target_link_libraries(TurtleMove_server ${catkin_LIBRARIES})
add_dependencies(TurtleMove_server ${PROJECT_NAME}_gencpp)

3、编译及运行

编译过程如图:

设置环境变量:

source ~/catkin_ws/devel/setup.bash

然后开始运行小海龟:

roscore
source ~/catkin_ws/devel/setup.bash
rosrun turtlesim turtlesim_node
source ~/catkin_ws/devel/setup.bash
rosrun learn_action TurtleMove_server
source ~/catkin_ws/devel/setup.bash
rosrun learn_action TurtleMove_client

最好如图所示,小海龟成功运行:

四、分布式通讯

在两台电脑上演示ROS的分布式通信

1、主机

两台电脑保证在一个局域网内,输入命令查看主机ip

ifconfig

开启ros

roscore

新建终端

export ROS_IP=xxx.xxx.xxx                           #本机IP
export ROS_MASTER_URI=http://xxx.xxx.xxx:11311/        #主机IP
rosrun turtlesim turtlesim_node
source ~/.bashrc

2、从机

开启一个终端,输入

export ROS_IP=X.X.X.X                       #本机ip
export ROS_MASTER_URI=http://x.x.x.x:11311 #主机IP
source ~/.bashrc
rosrun turtlesim turtle_teleop_key

3、运行结果

这里我没有两台电脑,就用了一台电脑上同时打开两台虚拟机做测试。
结果可以成功运行,在一台虚拟机上使用方向键操控另一台虚拟机上打开的小乌龟运行程序。

五、总结

动作编程是一种问答通讯机制,带有连续反馈,可以在任务过程中止运行。此次实验任务学习到的东西很多,需要话很多时间去学习消化,在前辈细致的博客指导下还是比较容易完成的。

六、参考资料

https://blog.csdn.net/qq_42585108/article/details/104852100

机器人操作系统ROS动作编程相关推荐

  1. 机器人操作系统ROS(6)动作编程

    注:在 catkin\_ws 工作空间下的功能包earning\_communication 下继续实现通信编程,参考上节-服务编程 一.动作通讯模型 二.动作编程实现 1. 自定义动作文件actio ...

  2. 机器人操作系统ROS 编程开发--详细总结

    最近工作涉及到自动驾驶的,需要学习ROS,学习中总结了一些知识点,分享给大家. ROS基本介绍 机器人操作系统ROS,是一种分布式处理框架(又名Nodes),ROS常用C++和python编程语言开发 ...

  3. 机器人操作系统ROS(4)话题编程

    此节的前提是已经创建好工作空间,请参考 工作空间 一.话题通讯模型 二.话题编程实现 1. 实现发布者(Talker) a.在~/catkin_ws/src/learning_communicaton ...

  4. 机器人操作系统ROS(5)服务编程

    在catkin\_ws工作空间下的功能包learning\_communication下继续实现通信编程,请参考上节-话题编程 一.服务通讯模型 二.服务编程实现 注:实现加法listener发布两个 ...

  5. python机器人编程教程入门_机器人操作系统(ROS)入门必备:机器人编程一学就会

    本书是针对机器人操作系统(ROS)初学者的入门教程,从基础的如何安装ROS,到ROS的框架介绍和C/C++.Python编程基础概念介绍,直至完整搭建一个机器人项目,每一个部分都有详细的操作过程和相应 ...

  6. 《机器人操作系统ROS原理与应用》——1.3 智能机器人的分类

    本节书摘来自华章出版社<机器人操作系统ROS原理与应用>一 书中的第1章,第1.3节,作者:周兴社 杨刚 王岚,更多章节内容可以访问云栖社区"华章计算机"公众号查看. ...

  7. 一文读懂自动驾驶中的机器人操作系统ROS

    一.什么是机器人操作系统ROS 1.ROS(Robot Operating System)是一个操作系统 ROS是对机器人的硬件进行了封装,不同的机器人.不同的传感器,在ROS里可以用相同的方式表示( ...

  8. 从零打造一个机器人002【初识机器人操作系统--ROS】

    从零打造一个机器人002[初识机器人操作系统–ROS] 1.ROS是什么 ROS是一个适用于机器人的开源的元操作系统.其实它并不是一个真正的操作系统,其底层的任务调度.编译.寻址等任务还是由Linux ...

  9. 关于机器人操作系统(ROS)学习前须知二三

    ROS基础资料 1.什么是ROS? ROS(机器人操作系统,Robot Operating System),是专为机器人软体开发所设计出来的一套电脑作业系统架构.它是一个开源的元级操作系统(后操作系统 ...

最新文章

  1. 【Java Web开发指南】解析Spring中Ioc和DI(入门Demo)
  2. 【安卓开发】Layout Inflation不能这么用
  3. SQLSERVER2014的内存优化表
  4. 如果测试你的MongoDB应用升级?
  5. Angular4中常用管道
  6. java 减少内存_java – 减少内存流失的方法
  7. 51Nod-1284 2 3 5 7的倍数【数位DP+记忆化搜索】
  8. 空降新书榜,霸占前三甲,还有什么是这些书做不到的?!
  9. 随机森林和GBDT的几个核心问题
  10. python gif_Python-字符版gif图
  11. 二十九 Python分布式爬虫打造搜索引擎Scrapy精讲—selenium模块是一个python操作浏览器软件的一个模块,可以实现js动态网页请求...
  12. Win10PE纯净版制作过程
  13. MariaDB数据库导出导入
  14. 模糊神经网络应用实例,神经网络与模糊控制
  15. Python正在慢慢褪色
  16. 安卓实现图片缩放平移的基本步骤
  17. table 超级详细的 商品订单列表
  18. 未封装的扩展程序是什么意思_晶圆级封装是什么意思?
  19. opencv2 加载RTSP视频流,内存溢出的问题
  20. 对接亚马逊 SP-API(Amazon Selling Partner API) 第六章:Fulfillment Inbound 模块

热门文章

  1. 深度学习网络量化白皮书论文学习
  2. 小体积掌上读数仪( MFang)掌上宝便携式振弦读数仪
  3. android usb vold,android Vold Usb
  4. Python学习日记-第二十九天-tcp(客户端)
  5. 狂暴者 pat basic 练习二十一 个位数统计
  6. Learn to See in the Dark 论文
  7. 努力不一定会成功,但成功却永远需要努力
  8. 《嵌入式系统 – NUC980 IoT应用开发实战指南(基于RT-Thread系统)》第1章 NUC980 IoT移植 RT-Thread
  9. 什么是SELINUX ?
  10. 只需要把脸对准摄像头就可以实现刷脸支付