ROS与Arduino学习(四)用ROS中的Cmake编译程序
Tutorial Level:订阅与发布
Next Tutorial:客户端与服务器
当需要开发大点的软件项目,Arduino IDE对代码的管理就变得比较笨拙。我们可以通过rosserial_client的CMake基础架构,也可以利用ROS buildfarm构建和分发固件。本节我们做一个简单的固件用以实现对舵机的控制。
Tips 1 创建功能包
在catkin工作空间下src目录下创建你的功能包。此处的工作区间你可以随意去弄,其实工作空间的布局如下:
workspace-----src------package1
-----devel
----build
此处的build和devel是在catkin_make后产生的,src文件夹是自己新建的,我们进入到src中,在src中开始利用命令行指令创建功能包。
$ cd ~/catkin_ws/src/ $ catkin_create_pkg test1 rosserial_arduino rosserial_client std_msgs
此处 test1 是你的功能包的名称,后面是他所依赖的程序包,包括arduino的消息包。
Tips 2 编写源文件
在package1中新建文件夹src文件夹(mkdir src),并在src中新建文件control.cpp(touch control.cpp)。如此创建完你的文件。编写如下程序文件。
#include <ros.h> #include <std_msgs/String.h> #include <std_msgs/UInt16.h> #include <Servo.h> #include <Arduino.h> Servo servo; ros::NodeHandle nh; std_msgs::String str_msg; //publish and subscribe // ros::Publisher pub("Arduino2PC",&str_msg); void Servo_Control(const std_msgs::UInt16& cmd_msg) { servo.write(cmd_msg.data); } ros::Subscriber <std_msgs::UInt16> sub("PC2Arduino", &Servo_Control ); char hello[]="hello world!"; void setup() { pinMode(9, OUTPUT); nh.initNode(); nh.advertise(pub);// publish nh.subscribe(sub);// subscribe servo.attach(9); //attach it to pin 9 } void loop() { str_msg.data = hello; pub.publish(&str_msg);//publish a message nh.spinOnce(); delay(1); }
程序解释:
1、需要调用servo.h文件,以及整形消息。
2、初始化函数
nh.advertise(pub);// publish nh.subscribe(sub);// subscribe
这两句话对句柄进行publish、subscribe实例化
servo.attach(9);
将舵机匹配到PIN9
Tips 3 编辑包目录下的CMakeLists.txt文件
主要需要注意两个地方,
1、rosserial_generate_ros_lib
rosserial_generate_ros_lib函数创建目标helloworld_ros_lib,它生成rosserial客户端库包含信息头
2、rosserial_configure_client
rosserial_configure_client函数用来对编译器进行配置,一方面是编译的程序目录,另一方面是所采取的工具连,这里rosserial_arduino提供了有用的Arduino工具链。
3、添加程序目标文件
rosserial_add_client_target(firmware hello ALL) rosserial_add_client_target(firmware hello-upload)
cmake_minimum_required(VERSION 2.8.3) project(helloworld) find_package(catkin REQUIRED COMPONENTS rosserial_arduino rosserial_client ) catkin_package() rosserial_generate_ros_lib( PACKAGE rosserial_arduino SCRIPT make_libraries.py ) rosserial_configure_client( DIRECTORY firmware TOOLCHAIN_FILE ${ROSSERIAL_ARDUINO_TOOLCHAIN} ) rosserial_add_client_target(firmware hello ALL) rosserial_add_client_target(firmware hello-upload)
Tips 4 包目录下创建firmware/CMakeLists.txt
在包目录下创建firmware/CMakeLists.txt, 这是需要的第二个CMakeLists.txt,这个是针对固件的子项目,内容如下:
注意几点:
generate_arduino_firmware
第一个参数是程序包名称test1
第二个参数是源文件control.cpp
第三个是板卡型号uno
第四个是串口号/dev/ttyUSB0
cmake_minimum_required(VERSION 2.8.3) include_directories(${ROS_LIB_DIR}) # Remove this if using an Arduino without native USB (eg, other than Leonardo) add_definitions(-DUSB_CON) generate_arduino_firmware(test1 SRCS control.cpp ${ROS_LIB_DIR}/time.cpp BOARD uno PORT /dev/ttyUSB0 )
Tips 5 编译及下载
编译
catkin_make test1_firmware_test1
下载
catkin_make test1_firmware_test1-upload
在此如果遇到错误,可能是USB配置错误,或者其他的,大概是上面配置不当。
Tips 6 测试
#新终端打开 $ roscore #新终端打开 $ rosrun rosserial_python serial_node.py _port:=/dev/ttyUSB0 #新终端打开 $ rostopic pub PC2Arduino std_msgs/UInt16 120