本文共 4654 字,大约阅读时间需要 15 分钟。
摘自:
VIP文章 2017-12-15 09:54:54 5582
分类专栏: 文章标签:
版权
在订阅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})
<?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();
}
}
我们订阅的是/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})
#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;
}
$cd ~/catkin_ws2/
$catkin_make
编译成功后输入 source /devel/setup.bash
三、串口助手
在另一台笔记本上下载安装串口调试助手,我们选择的是sscom33,百度云链接https://pan.baidu.com/s/1bo7WRrL
用串口线连接两台电脑。
四、测试
1、先运行用arbotix来模拟控制机械臂,这会启动/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的数据发生变化,如果连接了下位机和电机,便可手动控制真实机械臂。