做机械臂导航时遇到的问题5:如何使用ROS内嵌serial功能包实现串口通信

2023-05-16

 

摘自:https://blog.csdn.net/weixin_39579805/article/details/78809681?utm_medium=distribute.pc_relevant_t0.none-task-blog-OPENSEARCH-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-OPENSEARCH-1.channel_param

做机械臂导航时遇到的问题5:如何使用ROS内嵌serial功能包实现串口通信

 

VIP文章 立雪青松 2017-12-15 09:54:54 5582 收藏 5

分类专栏: 机械臂导航 文章标签: ROS 机械臂 joint_states 串口通信 serial

版权

    在订阅joint_states话题,获取到position和velocity的数据之后,如何将这些信息发给下位机呢?下位机都具备串口,我们通过串口实现与下位机的通讯。在本篇中,我们采用ROS内嵌的Serial功能包实现串口通讯,当然还有其他方式来实现。

这里参考各位大神的文章,在这里表示感谢:

1、ROS中串口的使用——serial功能包:点击链接

2、ROS串口通信:点击链接

 

一、建立工作目录并下载serial功能包

 


   
  1. $mkdir -p ~/catkin_ws2/src/mypackage/

  2. $cd ~/catkin_ws2/src/mypackage/

  3. $git clone https://github.com/wjwwood/serial.git


二、创建串口节点

 

1、在mypackage目录下建立串口节点程序包:

 

$catkin_create_pkg my_serial_node std_msgs rospy roscpp

 

生成文件效果如下:

 


 

2、修改 CMakeLists.txt,修改后内容如下:

 


   
  1. cmake_minimum_required(VERSION 2.8.3)

  2. project( my_serial_node )

  3. find_package(catkin REQUIRED COMPONENTS

  4. roscpp

  5. serial

  6. std_msgs

  7. )

  8.  
  9. catkin_package(

  10. CATKIN_DEPENDS

  11. serial

  12. std_msgs

  13. )

  14. include_directories(

  15. ${catkin_INCLUDE_DIRS}

  16. )

  17. add_executable( my_serial_node src/my_serial_node.cpp)

  18. target_link_libraries( my_serial_node

  19. ${catkin_LIBRARIES}

  20. )

  21. add_executable(talker src/talker.cpp)

  22. target_link_libraries(talker ${catkin_LIBRARIES})

  23.  
  24. add_executable(listener src/listener.cpp)

  25. target_link_libraries(listener ${catkin_LIBRARIES})


3、修改package.xml,添加刚刚下载的serial 依赖

 

 


   
  1. <?xml version="1.0"?>

  2. <package>

  3. <name> my_serial_node</name>

  4. <version>0.0.0</version>

  5. <description>my serial node </description>

  6.  
  7. <maintainer email="xs@todo.todo">xs</maintainer>

  8. <license>BSD</license>

  9. <buildtool_depend>catkin</buildtool_depend>

  10. <build_depend>serial</build_depend>

  11. <build_depend>std_msgs</build_depend>

  12. <run_depend>serial</run_depend>

  13. <run_depend>std_msgs</run_depend>

  14. </package>

 

 


4、在 mypackage/my_serial_node/src目录下创建my_serial_node.cpp 文件

 


   
  1. #include "ros/ros.h"

  2. #include <serial/serial.h>

  3. #include <std_msgs/String.h>

  4. #include <std_msgs/Empty.h>

  5. #include "sensor_msgs/JointState.h"

  6. #include <string>

  7. #include <sstream>

  8. serial::Serial ros_ser; //声明串口对象

  9. //回调函数

  10. void jointstatesCallback(const sensor_msgs::JointStateConstPtr& msg)

  11. {

  12. std::stringstream str;

  13. str<<"joint1: pos:"<<msg->position[2]<<" vel:"<<msg->velocity[2]

  14. <<" joint2: pos:"<<msg->position[0]<<" vel:"<<msg->velocity[0]

  15. <<" joint3: pos:"<<msg->position[1]<<" vel:"<<msg->velocity[1]<<std::endl;

  16. ROS_INFO_STREAM("Writing to serial port" );

  17. ros_ser.write(str.str()); //发送串口数据

  18. }

  19.  
  20. /*void callback(const std_msgs::String::ConstPtr& msg)

  21. {

  22. std::stringstream str;

  23. str<<"joint1: pos:"<<1.0<<" vel:"<<2.0<<std::endl;

  24. ROS_INFO_STREAM("Write to serial port" << msg->data);

  25. ros_ser.write(str.str()); //发送串口数据

  26. }*/

  27. int main (int argc, char** argv){

  28. ros::init(argc, argv, "my_serial_node"); //初始化节点

  29. ros::NodeHandle n; //声明节点句柄

  30. //订阅主题/joint_states,并配置回调函数

  31. ros::Subscriber command_sub = n.subscribe("/joint_states", 1000, jointstatesCallback);

  32. //发布主题sensor

  33. ros::Publisher sensor_pub = n.advertise<std_msgs::String>("sensor", 1000);

  34.  
  35. try

  36. {

  37. //设置串口属性,并打开串口

  38. ros_ser.setPort("/dev/ttyUSB0");

  39. ros_ser.setBaudrate(115200);

  40. serial::Timeout to = serial::Timeout::simpleTimeout(1000);

  41. ros_ser.setTimeout(to);

  42. ros_ser.open();

  43. }

  44. catch (serial::IOException& e)

  45. {

  46. ROS_ERROR_STREAM("Unable to open port ");

  47. return -1;

  48. }

  49.  
  50. //检测串口是否已经打开,并给出提示信息

  51. if(ros_ser.isOpen()){

  52. ROS_INFO_STREAM("Serial Port opened");

  53. }else{

  54. return -1;

  55. }

  56.  
  57. //指定循环的频率

  58. ros::Rate loop_rate(10);

  59.  
  60. while(ros::ok()){

  61.  
  62. //处理ROS的信息,比如订阅消息,并调用回调函数

  63. ros::spinOnce();

  64.  
  65. if(ros_ser.available()){

  66. ROS_INFO_STREAM("Reading from serial port");

  67. std_msgs::String serial_data;

  68. //获取串口数据

  69. serial_data.data = ros_ser.read(ros_ser.available());

  70. ROS_INFO_STREAM("Read: " << serial_data.data);

  71. //将串口数据发布到主题sensor

  72. sensor_pub.publish(serial_data);

  73. }

  74. loop_rate.sleep();

  75. }

  76. }


5、关于话题的发布者:由my_serial_node.cpp文件中的回调函数可知, ros::Subscriber command_sub = n.subscribe("/joint_states", 1000, jointstatesCallback);

 

我们订阅的是/joint_states话题。(做机械臂导航时遇到的问题4:如何订阅joint_states话题(输出关节状态))

 

6、创建listener节点,接收串口助手发送的信息

在 mypackage/my_serial_node/src目录下新建文件 listener.cpp ,并在 CMakeLists.txt 中添加以下内容(已在上述CMakeList中添加):

 


   
  1. add_executable(listener src/listener.cpp)

  2. target_link_libraries(listener ${catkin_LIBRARIES})


listener.cpp文件内容如下:

 

 


   
  1. #include "ros/ros.h"

  2. #include "std_msgs/String.h"

  3. //回调函数

  4. void callback(const std_msgs::String::ConstPtr& msg)

  5. {

  6. ROS_INFO("I heard: [%s]", msg->data.c_str());

  7. }

  8.  
  9. int main(int argc, char **argv)

  10. {

  11. ros::init(argc, argv, "listener");

  12. ros::NodeHandle n;

  13. //订阅主题,接收串口数据

  14. ros::Subscriber sub = n.subscribe("sensor", 1000, callback);

  15. ros::spin();

  16. return 0;

  17. }


7、编译

 

 


   
  1. $cd ~/catkin_ws2/

  2. $catkin_make

编译成功后输入 source /devel/setup.bash

 

 

三、串口助手

在另一台笔记本上下载安装串口调试助手,我们选择的是sscom33,百度云链接https://pan.baidu.com/s/1bo7WRrL

用串口线连接两台电脑。

 

四、测试

1、先运行用arbotix来模拟控制机械臂,这会启动/joint_states话题。参考(做机械臂导航遇到的问题3:如何用arbotix接口控制机械臂    做机械臂导航时遇到的问题4:如何订阅joint_states话题(输出关节状态))

2、在新终端运行$roscore

3、在新终端运行$rosrun my_serial_node my_serial_node

4、在新终端运行$rosrun my_serial_node listenner

my_serial_node终端效果如下

listener终端效果如下,可以接收串口助手发送的信息

另一台电脑串口助手效果如下,在arbotix gui窗口控制滑块时,可以看到相应joint1、joint2、joint3的数据发生变化,如果连接了下位机和电机,便可手动控制真实机械臂。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

做机械臂导航时遇到的问题5:如何使用ROS内嵌serial功能包实现串口通信 的相关文章

随机推荐