ROS2 与 Arduino Nano 通信指南
本指南介绍如何在Ubuntu环境下使用VSCode实现ROS2与Arduino Nano之间的通信。
环境准备
- Ubuntu系统安装ROS2
- VSCode安装以下扩展:
- PlatformIO IDE(Arduino开发)
- ROS(ROS2开发)
- C/C++
Arduino Nano 项目设置
-
使用PlatformIO创建新项目,选择Arduino Nano作为开发板。
-
在
src/main.cpp
中编写Arduino代码,实现ROS通信功能。示例代码如下:
#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 <std_msgs/msg/int32.h>
rcl_publisher_t publisher;
std_msgs__msg__Int32 msg;
rclc_executor_t executor;
rcl_allocator_t allocator;
rclc_support_t support;
rcl_node_t node;
#define LED_PIN 13
#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 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(std_msgs, msg, Int32),
"micro_ros_arduino_node_publisher"));
msg.data = 0;
}
void loop() {
RCSOFTCHECK(rcl_publish(&publisher, &msg, NULL));
msg.data++;
delay(100);
}
- 在
platformio.ini
中配置必要的库依赖:
[env:nanoatmega328]
platform = atmelavr
board = nanoatmega328
framework = arduino
lib_deps =
https://github.com/micro-ROS/micro_ros_platformio
ROS2 工作空间设置
- 创建ROS2工作空间和功能包:
mkdir -p ros2_ws/src
cd ros2_ws/src
ros2 pkg create --build-type ament_python my_micro_ros_pkg
-
在功能包中创建ROS2节点:
a. 进入功能包目录:
cd my_micro_ros_pkg
b. 在
my_micro_ros_pkg
目录下创建一个新的Python文件,命名为micro_ros_listener.py
:touch my_micro_ros_pkg/micro_ros_listener.py
c. 使用VSCode或其他文本编辑器打开
micro_ros_listener.py
,并添加以下代码:import rclpy from rclpy.node import Node from std_msgs.msg import Int32 # 假设Arduino发送的是Int32消息,根据实际情况调整 class MicroROSListener(Node): def __init__(self): super().__init__('micro_ros_listener') self.subscription = self.create_subscription( Int32, 'micro_ros_arduino_node_publisher', # 这应该与Arduino代码中发布的话题名称匹配 self.listener_callback, 10) self.subscription # 防止未使用的变量警告 def listener_callback(self, msg): self.get_logger().info('I heard: "%d"' % msg.data) def main(args=None): rclpy.init(args=args) micro_ros_listener = MicroROSListener() rclpy.spin(micro_ros_listener) micro_ros_listener.destroy_node() rclpy.shutdown() if __name__ == '__main__': main()
d. 修改
setup.py
文件以包含新的节点。打开setup.py
并在entry_points
部分添加以下内容:entry_points={ 'console_scripts': [ 'micro_ros_listener = my_micro_ros_pkg.micro_ros_listener:main', ], },
e. 更新
package.xml
文件,添加必要的依赖:<depend>rclpy</depend> <depend>std_msgs</depend>
-
构建功能包:
cd ~/ros2_ws
colcon build
source install/setup.bash
运行通信
-
确保 Arduino 代码已经编译并上传到板子上。
-
在一个终端中运行 micro-ROS 代理:
ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyUSB0
注意:如果你的 Arduino 连接到不同的端口,请相应地更改
/dev/ttyUSB0
。 -
在另一个终端中,运行你的 ROS2 监听节点:
ros2 run my_micro_ros_pkg micro_ros_listener
-
你应该能看到来自 Arduino 的消息被打印出来。
-
如果你想发送命令到 Arduino,你可以使用 ROS2 的话题发布功能。例如:
ros2 topic pub /your_command_topic std_msgs/msg/String "data: 'your command'"
注意:确保将
/your_command_topic
替换为你在 Arduino 代码中订阅的实际话题名称。 -
要查看所有可用的话题,可以运行:
ros2 topic list
-
要查看话题的详细信息,如消息类型,可以运行:
ros2 topic info /topic_name
注意:确保在运行这些命令之前,你已经 source 了你的 ROS2 环境:
source /opt/ros/humble/setup.bash
source ~/ros2_ws/install/setup.bash
预期效果
成功实现通信后,您应能看到以下效果:
- micro-ROS 代理终端会显示连接成功的信息。
- 在运行
micro_ros_listener
的终端中,您将看到来自 Arduino 的消息被打印出来。 - 如果您发布命令到 Arduino,您可能会在 Arduino 的行为或输出中看到相应的变化,具体取决于您的代码实现。
通过观察这些输出,您可以确认 ROS2 和 Arduino 之间的通信是否正常工作。
注意事项
- 确保Arduino Nano正确连接到Ubuntu系统。
- 可能需要调整串口设备名(如/dev/ttyUSB0)和波特率。
- 根据实际需求修改话题名称和消息类型。
通过以上步骤,您应该能够在VSCode中完成ROS2和Arduino Nano的开发,实现它们之间的通信,并观察到通信的实际效果。