天津大学 工学博士
参考:https://github.com/micro-ROS/micro_ros_arduino
https://blog.csdn.net/ZhangRelay/article/details/101394537
本文所用安装环境:
参考我之前写的一篇记录micro_ros配置记录 - 知乎
特别注意:
我这里使用的下位机是M5stack Atom Lite,其核心是esp32,但我用arduino框架进行开发。
理论上,所有支持arduino开发的嵌入式平台应该都可以。
注意:务必安装自己嵌入式平台对应的arduino支持包。
正确安装M5stack支持包后,在开发板管理中应该出现M5 stack相关的信息。
image-20220716210240849
- #include <micro_ros_arduino.h>
-
- #include <stdio.h>
- #include <rcl/rcl.h>
- #include <rcl/error_handling.h>
- #include <rclc/rclc.h>
- #include <rclc/executor.h>
-
- #include <geometry_msgs/msg/twist.h> //changed!
-
- rcl_publisher_t publisher;
- geometry_msgs__msg__Twist msg; //changed!-->modify msg type <twist__struct.h>
- rclc_executor_t executor;
- rclc_support_t support;
- rcl_allocator_t allocator;
- rcl_node_t node;
- rcl_timer_t timer;
-
- #define LED_PIN 27 //changed!-->Modify M5 stack Atom Lite LED pin
-
- #define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}}
- #define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}}
-
- void error_loop(){
- while(1){
- digitalWrite(LED_PIN, !digitalRead(LED_PIN));
- delay(100);
- }
- }
-
- void timer_callback(rcl_timer_t * timer, int64_t last_call_time)
- {
- RCLC_UNUSED(last_call_time);
- if (timer != NULL) {
- RCSOFTCHECK(rcl_publish(&publisher, &msg, NULL));
-
- static int cnt = 0;
- msg.linear.x = 0.2; //const linear.x
- msg.angular.z = 1.0 - 0.001*cnt; //variable angular.z
- cnt++;
- }
- }
-
- void setup() {
- set_microros_transports();
-
- pinMode(LED_PIN, OUTPUT);
- digitalWrite(LED_PIN, HIGH);
-
- delay(2000);
-
- allocator = rcl_get_default_allocator();
-
- //create init_options
- RCCHECK(rclc_support_init(&support, 0, NULL, &allocator));
-
- // create node
- RCCHECK(rclc_node_init_default(&node, "micro_ros_arduino_node", "", &support));
-
- // create publisher
- RCCHECK(rclc_publisher_init_default(
- &publisher,
- &node,
- ROSIDL_GET_MSG_TYPE_SUPPORT(geometry_msgs, msg, Twist),
- "turtle1/cmd_vel")); //changed!-->modify topic name
-
- // create timer,
- const unsigned int timer_timeout = 1000;
- RCCHECK(rclc_timer_init_default(
- &timer,
- &support,
- RCL_MS_TO_NS(timer_timeout),
- timer_callback));
-
- // create executor
- RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator));
- RCCHECK(rclc_executor_add_timer(&executor, &timer));
-
- // changed!-->msg initialization
- msg.linear.x=0;
- msg.linear.y=0;
- msg.linear.z=0;
- msg.angular.x=0;
- msg.angular.y=0;
- msg.angular.z=0;
- }
-
- void loop() {
- delay(100);
- RCSOFTCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100)));
- }
- #include <geometry_msgs/msg/twist.h> //changed!
- geometry_msgs__msg__Twist msg; //changed!-->modify msg type <twist__struct.h>
- // changed!-->msg initialization
- msg.linear.x=0;
- msg.linear.y=0;
- msg.linear.z=0;
- msg.angular.x=0;
- msg.angular.y=0;
- msg.angular.z=0;
// create publisher RCCHECK(rclc_publisher_init_default( &publisher, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(geometry_msgs, msg, Twist), "turtle1/cmd_vel")); //changed!-->modify topic name
- void timer_callback(rcl_timer_t * timer, int64_t last_call_time)
- {
- RCLC_UNUSED(last_call_time);
- if (timer != NULL)
- {
- RCSOFTCHECK(rcl_publish(&publisher, &msg, NULL));
- static int cnt = 0;
- msg.linear.x = 0.2; //const linear.x
- msg.angular.z = 1.0 - 0.001*cnt; //variable angular.z
- cnt++;
- }
- }
将下位机代码烧录后,将下位机通过串口连接上位机,这里我使用usb串口的方式连接。
微信图片_20220717085646
为了显示turtle的运动,旭日x3派需要连接hdmi或者远程VNC,我使用的后者。
新建终端,source一下ros2,再source一下micro_ros。
- source /opt/tros/setup.bash #或者 source /opt/ros/foxy/setup.bash
- cd /microros_ws/ #进入micro_ros的工作空间
- source install/setup.bash #source一下,也可以将这些命令添加到 /.bashrc
sudo chmod -R 777 /dev/ttyUSB0
ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyUSB0
image-20220717084958430
ros2 run turtlesim turtlesim_node
image-20220717085058875