用键盘控制ESP32亮灯
编辑上位机
1.建立package
source /opt/ros/humble/setup.bash
ros2 pkg create --build-type ament_python my_ros_py_package
2.有一个通过键盘按键值转换为ASCII值的节点发布topic消息
命名为 keyboard_asc_publisher.py
import rclpy
from rclpy.node import Node
from std_msgs.msg import Int32
from pynput import keyboard
class KeyboardPublisher(Node):
def __init__(self):
super().__init__('keyboard_publisher')
self.publisher_ = self.create_publisher(Int32, 'topic_name', 10)
self.listener = keyboard.Listener(on_press=self.on_press)
self.listener.start()
def on_press(self, key):
if hasattr(key, 'char') and key.char:
key_char = key.char
ascii_value = ord(key_char)
msg = Int32()
msg.data = ascii_value
self.publisher_.publish(msg)
self.get_logger().info(f'Publishing: {msg.data}')
def main(args=None):
rclpy.init(args=args)
node = KeyboardPublisher()
try:
rclpy.spin(node)
except KeyboardInterrupt:
pass
finally:
node.listener.stop()
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
3. 如果需要的话,可以在上位机上创建一个subscriber,来查看收到的消息:
subscriber.py
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class MySubscriber(Node):
def __init__(self):
super().__init__('my_subscriber_node')
self.subscription = self.create_subscription(
int,
'topic_name',
self.listener_callback,
10)
self.subscription # prevent unused variable warning
def listener_callback(self, msg):
self.get_logger().info(f"I heard: '{msg.data}'")
def main(args=None):
rclpy.init(args=args)
node = MySubscriber()
rclpy.spin(node)
rclpy.shutdown()
if __name__ == '__main__':
main()
4.编写一个launch 可以同时运行这两个节点(node)
(1)创建launch目录
mkdir -p my_ros_py_package/launch
(2)编写launch文件
在launch目录中创建一个新的Python文件,例如my_launch.py,然后添加以下内容:
touch my_launch.py
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(
package='my_ros_py_package',
executable='subscriber',
name='subscriber_node'
),
Node(
package='my_ros_py_package',
executable='keyboard_asc_publisher',
name='keyboard_asc_publisher_node'
)
])
(3)确保launch文件在正确的位置
my_ros_py_package/
|-- launch/
| |-- my_launch.py
|-- my_ros_py_package/
| |-- __init__.py
| |-- subscriber.py
| |-- keyboard_publisher.py
| |-- keyboard_asc_publisher.py
|-- setup.py
|-- package.xml
(4)在setup.py中声明launch文件
修改setup.py文件,以确保launch文件夹中的文件被正确安装。在data_files参数中添加一个条目来包含launch目录:
from setuptools import setup, find_packages
package_name = 'my_ros_py_package'
setup(
name=package_name,
# other setup parameters...
data_files=[
('share/ament_index/resource_index/packages',
['resource/' + package_name]),
('share/' + package_name, ['package.xml']),
('share/' + package_name + '/launch', ['launch/my_launch.py']), # Add this line
],
# other setup parameters...
)
(5)重新构建和安装包
在更改setup.py文件后,您需要重新构建和安装您的ROS 2包:
cd ~/Documents/topicComTest # Adjust this path to where your workspace is
colcon build
(6)运行launch文件
现在应该可以运行launch文件了:
ros2 launch my_ros_py_package my_launch.py
如果不出意外的话,应该可以看到2个节点和一个topic已经运行起来了。这个时候可以运行rqt_graph来查看已经运行的节点和topic。
类似下图:

编辑下位机(esp32)
1. 新建工程 并 添加支持库
[env:featheresp32]
platform = espressif32
board = featheresp32
framework = arduino
lib_deps =
https://gitee.com/harebert/micro_ros_platformio.git
2.编写main.cpp
#include <Arduino.h>
#include <micro_ros_platformio.h>
#include <rcl/rcl.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>
#include <std_msgs/msg/int32.h>
rclc_executor_t executor;
rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;
// 声明话题订阅者
rcl_subscription_t subscriber;
// 声明消息文件
std_msgs__msg__Int32 sub_msg;
// 定义话题接收回调函数
void callback_subscription_(const void *msgin)
{
const std_msgs__msg__Int32 *msg = (const std_msgs__msg__Int32 *)msgin;
if (msg->data > 100)
{
digitalWrite(2, HIGH); //如果接受到的值大于100,即大于d,则灭灯
}
else
{
digitalWrite(2, LOW);//如果接受到的值小于100,即小于等于d,则亮灯
}
}
void setup()
{
Serial.begin(115200);
// 设置通过串口进行MicroROS通信
set_microros_serial_transports(Serial);
// 延时时一段时间,等待设置完成
delay(2000);
// 初始化内存分配器
allocator = rcl_get_default_allocator();
// 创建初始化选项
rclc_support_init(&support, 0, NULL, &allocator);
// 创建节点 topic_sub_test
rclc_node_init_default(&node, "esp32Car", "", &support);
// 订阅者初始化
rclc_subscription_init_default(
&subscriber,
&node,
ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
"topic_name");
// 创建执行器
rclc_executor_init(&executor, &support.context, 1, &allocator);
// 为执行器添加一个订阅者
rclc_executor_add_subscription(&executor, &subscriber, &sub_msg, &callback_subscription_, ON_NEW_DATA);
// 初始化LED
pinMode(2, OUTPUT);
}
void loop()
{
delay(100);
// 循环处理数据
rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100));
}
保存编译并上传。
建立上位机和下位机的联系
Agen其实就是一个代理,微控制器可以通过串口,蓝牙、以太网、Wifi等多种协议将数据传递给Agent,Agent再将其转换成ROS2的话题等数据,以此完成通信。

所以接下里打开新的终端,并且运行agent
sudo docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:$ROS_DISTRO serial --dev /dev/ttyUSB0 -v
3万+



被折叠的 条评论
为什么被折叠?



