做工程時需要在樹莓派進行串口通信。具體爲接收到某個ROS的topic數據後,向串口下發數據。代碼編寫有兩種方法。
方法一:藉助serial庫
1、運行環境爲ubuntu,首先安裝serial庫:
sudo apt-get install serial
2、配置編寫的package中的CMakeLists.txt
在find_package中添加serial;
3、給設備的USB端口權限;
4、代碼範例:
manipulator_ros_serial.cpp
#include <ros/ros.h>
#include <string>
#include <serial/serial.h>
#include <std_msgs/Int64.h>
#define sBUFFERSIZE 7
unsigned char s_buffer[sBUFFERSIZE];
using namespace std;
serial::Serial ser;
//trans different serial cmds according to different action_cmd(joystick button)
void write_action_cmd(const std_msgs::Int64& action_cmd){
memset(s_buffer,0,sizeof(s_buffer));
if( 1 == action_cmd.data ){
s_buffer[0] = 0x55;
s_buffer[1] = 0x55;
s_buffer[2] = 0x05;
s_buffer[3] = 0x06;
s_buffer[4] = 0x01;
s_buffer[5] = 0x01;
s_buffer[6] = 0x00;
//std::cout<<"cmd has been received and published!!!"<<&std::endl;
}
ser.write(s_buffer,sBUFFERSIZE);
}
int main(int argc, char** argv){
ros::init(argc, argv, "manipulator_ros_serial_node");
ros::NodeHandle nh;
ros::NodeHandle nh_private("~");
std::string serial_port_;
int baudrate_;
nh_private.param<std::string>("serial_port", serial_port_, "/dev/ttyUSB0");
nh_private.param<int>("baudrate", baudrate_, 9600);
std::cout<<"The serial port is "<<serial_port_<<" ..."<<&std::endl;
std::cout<<"The baudrate is "<<baudrate_<<" ..."<<&std::endl;
ros::Subscriber write_sub = nh.subscribe("joystick/manipulator", 1000, write_action_cmd);
try
{
ser.setPort(serial_port_);
ser.setBaudrate(baudrate_);
serial::Timeout to = serial::Timeout::simpleTimeout(1000);
ser.setTimeout(to);
ser.open();
}
catch(serial::IOException& e){
ROS_ERROR_STREAM("Unable to open port!!!");
return -1;
}
if(ser.isOpen()){
ROS_INFO_STREAM("Serial Port initialized...");
}
else{
return -1;
}
ros::Rate loop_rate(50);
while(ros::ok()) {
ros::spinOnce();
loop_rate.sleep();
}
}
5、USB端口號和波特率都能通過launch文件配置。
manipulator_ros_serial.launch
<launch>
<node pkg="manipulator_ros_serial" name="manipulator_ros_serial" type="manipulator_ros_serial" output="screen">
<param name="serial_port" type="string" value="/dev/ttyUSB0" />
<param name="baudrate" type="int" value="9600" />
</node>
</launch>
方法二:藉助boost
1、運行環境爲raspbian,raspbian沒有serial庫;
2、代碼範例
manipulator_ros.h
#ifndef MANIPULATOR_SERIAL_H_
#define MANIPULATOR_SERIAL_H_
#include <ros/ros.h>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <std_msgs/Int64.h>
#include <string>
boost::asio::io_service io;
boost::asio::serial_port sp(io);
namespace manipulator_serial_namespace{
class ManipulatorSerial{
public:
ManipulatorSerial();
~ManipulatorSerial();
ros::Subscriber write_sub;
//boost::asio::io_service io;
void write_action_cmd(const std_msgs::Int64& action_cmd);
};
}
#endif
manipulator_serial.cpp
#include <manipulator_serial/manipulator_serial.h>
#define sBUFFERSIZE 7
unsigned char s_buffer[sBUFFERSIZE];
using namespace std;
using namespace boost::asio;
namespace manipulator_serial_namespace{
ManipulatorSerial::ManipulatorSerial(){
ros::NodeHandle nh;
ros::NodeHandle nh_private("~");
std::string serial_port_;
int baudrate_;
nh_private.param<std::string>("serial_port", serial_port_, "/dev/ttyUSB0");
nh_private.param<int>("baudrate", baudrate_, 9600);
std::cout<<"The serial port is "<<serial_port_<<" ..."<<&std::endl;
std::cout<<"The baudrate is "<<baudrate_<<" ..."<<&std::endl;
sp.open(serial_port_);
write_sub = nh.subscribe("joystick/manipulator", 1000, &ManipulatorSerial::write_action_cmd, this);
ros::spin();
}
ManipulatorSerial::~ManipulatorSerial(){}
void ManipulatorSerial::write_action_cmd(const std_msgs::Int64& action_cmd){
memset(s_buffer,0,sizeof(s_buffer));
if( 1 == action_cmd.data ){
s_buffer[0] = 0x55;
s_buffer[1] = 0x55;
s_buffer[2] = 0x05;
s_buffer[3] = 0x06;
s_buffer[4] = 0x01;
s_buffer[5] = 0x01;
s_buffer[6] = 0x00;
//std::cout<<"cmd has been received and published!!!"<<&std::endl;
}
boost::asio::write(sp, boost::asio::buffer(s_buffer));
}
}
int main(int argc, char** argv) {
::ros::init(argc, argv, "manipulator_serial_node");
::ros::start();
manipulator_serial_namespace::ManipulatorSerial a;
::ros::shutdown();
}
5、USB端口號和波特率都能通過launch文件進行配置。
manipulator_serial.launch
<launch>
<node pkg="manipulator_serial" name="manipulator_serial" type="manipulator_serial" output="screen">
<param name="serial_port" type="string" value="/dev/ttyUSB0" />
<param name="baudrate" type="int" value="9600" />
</node>
</launch>