摘自: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功能包
-
$mkdir -p ~/catkin_ws2/src/mypackage/
-
$cd ~/catkin_ws2/src/mypackage/
-
$git clone https://github.com/wjwwood/serial.git
二、创建串口节点
1、在mypackage目录下建立串口节点程序包:
$catkin_create_pkg my_serial_node std_msgs rospy roscpp
生成文件效果如下:
2、修改 CMakeLists.txt,修改后内容如下:
-
cmake_minimum_required(VERSION 2.8.3)
-
project( my_serial_node )
-
find_package(catkin REQUIRED COMPONENTS
-
roscpp
-
serial
-
std_msgs
-
)
-
-
catkin_package(
-
CATKIN_DEPENDS
-
serial
-
std_msgs
-
)
-
include_directories(
-
${catkin_INCLUDE_DIRS}
-
)
-
add_executable( my_serial_node src/my_serial_node.cpp)
-
target_link_libraries( my_serial_node
-
${catkin_LIBRARIES}
-
)
-
add_executable(talker src/talker.cpp)
-
target_link_libraries(talker ${catkin_LIBRARIES})
-
-
add_executable(listener src/listener.cpp)
-
target_link_libraries(listener ${catkin_LIBRARIES})
3、修改package.xml,添加刚刚下载的serial 依赖
-
<?xml version="1.0"?>
-
<package>
-
<name> my_serial_node</name>
-
<version>0.0.0</version>
-
<description>my serial node </description>
-
-
<maintainer email="xs@todo.todo">xs</maintainer>
-
<license>BSD</license>
-
<buildtool_depend>catkin</buildtool_depend>
-
<build_depend>serial</build_depend>
-
<build_depend>std_msgs</build_depend>
-
<run_depend>serial</run_depend>
-
<run_depend>std_msgs</run_depend>
-
</package>
4、在 mypackage/my_serial_node/src目录下创建my_serial_node.cpp 文件
-
#include "ros/ros.h"
-
#include <serial/serial.h>
-
#include <std_msgs/String.h>
-
#include <std_msgs/Empty.h>
-
#include "sensor_msgs/JointState.h"
-
#include <string>
-
#include <sstream>
-
serial::Serial ros_ser; //声明串口对象
-
//回调函数
-
void jointstatesCallback(const sensor_msgs::JointStateConstPtr& msg)
-
{
-
std::stringstream str;
-
str<<"joint1: pos:"<<msg->position[2]<<" vel:"<<msg->velocity[2]
-
<<" joint2: pos:"<<msg->position[0]<<" vel:"<<msg->velocity[0]
-
<<" joint3: pos:"<<msg->position[1]<<" vel:"<<msg->velocity[1]<<std::endl;
-
ROS_INFO_STREAM("Writing to serial port" );
-
ros_ser.write(str.str()); //发送串口数据
-
}
-
-
/*void callback(const std_msgs::String::ConstPtr& msg)
-
{
-
std::stringstream str;
-
str<<"joint1: pos:"<<1.0<<" vel:"<<2.0<<std::endl;
-
ROS_INFO_STREAM("Write to serial port" << msg->data);
-
ros_ser.write(str.str()); //发送串口数据
-
}*/
-
int main (int argc, char** argv){
-
ros::init(argc, argv, "my_serial_node"); //初始化节点
-
ros::NodeHandle n; //声明节点句柄
-
//订阅主题/joint_states,并配置回调函数
-
ros::Subscriber command_sub = n.subscribe("/joint_states", 1000, jointstatesCallback);
-
//发布主题sensor
-
ros::Publisher sensor_pub = n.advertise<std_msgs::String>("sensor", 1000);
-
-
try
-
{
-
//设置串口属性,并打开串口
-
ros_ser.setPort("/dev/ttyUSB0");
-
ros_ser.setBaudrate(115200);
-
serial::Timeout to = serial::Timeout::simpleTimeout(1000);
-
ros_ser.setTimeout(to);
-
ros_ser.open();
-
}
-
catch (serial::IOException& e)
-
{
-
ROS_ERROR_STREAM("Unable to open port ");
-
return -1;
-
}
-
-
//检测串口是否已经打开,并给出提示信息
-
if(ros_ser.isOpen()){
-
ROS_INFO_STREAM("Serial Port opened");
-
}else{
-
return -1;
-
}
-
-
//指定循环的频率
-
ros::Rate loop_rate(10);
-
-
while(ros::ok()){
-
-
//处理ROS的信息,比如订阅消息,并调用回调函数
-
ros::spinOnce();
-
-
if(ros_ser.available()){
-
ROS_INFO_STREAM("Reading from serial port");
-
std_msgs::String serial_data;
-
//获取串口数据
-
serial_data.data = ros_ser.read(ros_ser.available());
-
ROS_INFO_STREAM("Read: " << serial_data.data);
-
//将串口数据发布到主题sensor
-
sensor_pub.publish(serial_data);
-
}
-
loop_rate.sleep();
-
}
-
}
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中添加):
-
add_executable(listener src/listener.cpp)
-
target_link_libraries(listener ${catkin_LIBRARIES})
listener.cpp文件内容如下:
-
#include "ros/ros.h"
-
#include "std_msgs/String.h"
-
//回调函数
-
void callback(const std_msgs::String::ConstPtr& msg)
-
{
-
ROS_INFO("I heard: [%s]", msg->data.c_str());
-
}
-
-
int main(int argc, char **argv)
-
{
-
ros::init(argc, argv, "listener");
-
ros::NodeHandle n;
-
//订阅主题,接收串口数据
-
ros::Subscriber sub = n.subscribe("sensor", 1000, callback);
-
ros::spin();
-
return 0;
-
}
7、编译
-
$cd ~/catkin_ws2/
-
$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(使用前将#替换为@)