【ROS2机器人入门到实战】做个遥控车-订阅ROS2 Twist

6.做个遥控车-订阅ROS2 Twist

写在前面

  1. 当前平台文章汇总地址:ROS2机器人从入门到实战
  2. 获取完整教程及配套资料代码,请关注公众号<鱼香ROS>获取
  3. 教程配套机器人开发平台:两驱版| 四驱版
  4. 为方便交流,搭建了机器人技术问答社区:地址 fishros.org.cn

你好,我是小鱼。本节我们结合上一节电机控制以及前面章节的MicroROS话题订阅部分知识点,来实现一个可以用键盘遥控的小车。

一、新建工程

新建工程example24_ros2_car

在这里插入图片描述

修改配置

[env:featheresp32]  ; 这是一个环境配置标签,指定了代码将运行的硬件平台和框架
platform = espressif32  ; 指定了使用的平台为Espressif 32
board = featheresp32  ; 指定使用的硬件板为Feather ESP32
framework = arduino  ; 指定使用的框架为Arduino
board_microros_transport = wifi  ; 指定使用的Micro-ROS传输方式为Wi-Fi
lib_deps =  ; 列出所有依赖库的URL,这些库将被下载和安装
	https://github.com/fishros/Esp32McpwmMotor.git  ; ESP32-MCPWM-Motor库,用于驱动电机
    https://gitee.com/ohhuo/micro_ros_platformio.git  ; Micro-ROS平台库,用于在ESP32上运行ROS 2

二、编写代码

#include <Arduino.h>
#include <Esp32McpwmMotor.h>
#include <Arduino.h>
#include <micro_ros_platformio.h>
#include <WiFi.h>
#include <rcl/rcl.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>
#include <geometry_msgs/msg/twist.h>

// 定义 ROS2 执行器和支持结构
rclc_executor_t executor;
rclc_support_t support;
// 定义 ROS2 内存分配器
rcl_allocator_t allocator;
// 定义 ROS2 节点和订阅者
rcl_node_t node;
rcl_subscription_t subscriber;
// 定义接收到的消息结构体
geometry_msgs__msg__Twist sub_msg;

// 定义控制两个电机的对象
Esp32McpwmMotor motor;

// 回调函数,当接收到新的 Twist 消息时会被调用
void twist_callback(const void *msg_in)
{
  // 将接收到的消息指针转化为 geometry_msgs__msg__Twist 类型
  const geometry_msgs__msg__Twist *twist_msg = (const geometry_msgs__msg__Twist *)msg_in;
  // 从 Twist 消息中获取线速度和角速度
  float linear_x = twist_msg->linear.x;
  float angular_z = twist_msg->angular.z;
  // 打印接收到的速度信息
  Serial.printf("recv spped(%f,%f)\n", linear_x, angular_z);
  // 如果速度为零,则停止两个电机
  if (linear_x == 0 && angular_z == 0)
  {
    motor.updateMotorSpeed(0, 0);
    motor.updateMotorSpeed(1, 0);
    return;
  }

  // 根据线速度和角速度控制两个电机的转速
  if (linear_x > 0)
  {
    motor.updateMotorSpeed(0, 70);
    motor.updateMotorSpeed(1, 70);
  }

  if (linear_x < 0)
  {
    motor.updateMotorSpeed(0, -70);
    motor.updateMotorSpeed(1, -70);
  }

  if (angular_z > 0)
  {
    motor.updateMotorSpeed(0, -70);
    motor.updateMotorSpeed(1, 70);
  }

  if (angular_z < 0)
  {
    motor.updateMotorSpeed(0, 70);
    motor.updateMotorSpeed(1, -70);
  }
}

void setup()
{
  // 初始化串口
  Serial.begin(115200);

  // 初始化两个电机的引脚
  motor.attachMotor(0, 22, 23);
  motor.attachMotor(1, 12, 13);

  // 设置 micro-ROS 通信参数,连接到指定的 ROS2 代理
  IPAddress agent_ip;
  agent_ip.fromString("192.168.2.105");
  set_microros_wifi_transports("fishbot", "12345678", agent_ip, 8888);
  delay(2000);

  // 初始化 ROS2 执行器和支持结构
  allocator = rcl_get_default_allocator();
  rclc_support_init(&support, 0, NULL, &allocator);
  // 初始化 ROS2 节点
  rclc_node_init_default(&node, "esp32_car", "", &support);
  // 初始化订阅者
  rclc_subscription_init_default(
      &subscriber,
      &node,
      ROSIDL_GET_MSG_TYPE_SUPPORT(geometry_msgs, msg, Twist),
      "/cmd_vel");
  rclc_executor_init(&executor, &support.context, 1, &allocator);
  // 设置订阅的回调函数
  rclc_executor_add_subscription(&executor, &subscriber, &sub_msg, &twist_callback, ON_NEW_DATA);
}

void loop()
{
  rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100)); // 循环处理数据
}

代码使用 Esp32McpwmMotor 库初始化电机,设置 micro-ROS 通信参数以连接到 ROS2 代理,并初始化一个 ROS2 节点和一个订阅者,以订阅 /cmd_vel 主题上的 Twist 消息。

当接收到新的 Twist 消息时,调用 twist_callback() 函数提取线性和角速度,并相应地控制电机。如果两个速度都为零,则电机停止。否则,根据方向设置电机速度。在正向方向上,速度设置为 70,在反向方向上为 -70。

loop() 函数重复调用 rclc_executor_spin_some() 来处理来自 ROS2 网络的传入数据。

需要注意的是,你要根据自己的网络情况修改下面的代码以实现无线通信,如果不知道怎么设置,请回看前面章节。

agent_ip.fromString("192.168.2.105");
set_microros_wifi_transports("fishbot", "12345678", agent_ip, 8888);

三、下载测试

将代码下载到小车,运行agent,点击RST等待接入。

sudo docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:$ROS_DISTRO udp4 --port 8888 -v6

在这里插入图片描述

接着我们使用ROS 2的键盘控制节点来进行控制测试

ros2 run teleop_twist_keyboard teleop_twist_keyboard

在这里插入图片描述

接着按下入JKL,几个按键,看一下小车是否动了起来。

在这里插入图片描述

四、总结

本节我们通过将小车接入MicroROS完成了一个遥控小车的开发。下一节我们开始使用编码器来测量轮子的转速。

### 使用ROS2实现遥控汽车转向功能 #### 背景介绍 在现代机器人技术中,ROS(Robot Operating System)是一个广泛使用的开源框架,而其下一代版本ROS2则提供了更强的实时性和分布式能力。对于遥控汽车的应用场景,可以通过ROS2中的消息传递机制来实现转向控制。 根据已有的资料[^1]和[^2],可以了解到基于STM32控制器的硬件设计以及塔克创新提供的多种机器人开发平台能够很好地适配ROS环境下的应用需求。此外,针对特定底盘如麦克纳姆轮机器人的通信驱动已经存在成熟的解决方案[^3]。 以下是关于如何使用ROS2实现遥控汽车转向功能的具体方案: --- #### 方案概述 为了实现遥控汽车的转向功能,通常需要以下几个模块的支持: 1. **底层硬件接口**:负责接收来自上位机的速度指令并通过串口或其他方式发送给电机驱动器。 2. **ROS节点逻辑**:订阅`/cmd_vel`话题并解析其中的速度命令;同时发布`/odom`话题以反馈当前车辆的状态。 3. **运动学计算**:依据具体车型(例如两轮差速模型),完成从线速度与角速度到各轮独立转速之间的转换[^4]。 下面分别详细介绍这些部分的内容及其对应的代码示例。 --- #### 底层硬件接口 假设我们正在处理的是一个标准两轮差速移动平台,则可以根据前述提到的方法构建相应的固件程序运行于MCU之上。这里给出一段伪代码表示基本流程: ```c++ #include <Arduino.h> #define LEFT_MOTOR_PIN 9 #define RIGHT_MOTOR_PIN 10 void setup() { Serial.begin(115200); // 初始化串口通讯波特率 } void loop() { if (Serial.available()) { // 如果有新数据到达 int leftSpeed = Serial.parseInt(); // 获取左侧马达目标速度 int rightSpeed = Serial.parseInt(); // 获取右侧马达目标速度 analogWrite(LEFT_MOTOR_PIN, abs(leftSpeed)); // 设置左轮PWM占空比 digitalWrite(LEFT_MOTOR_PIN + 1, leftSpeed >= 0 ? HIGH : LOW); analogWrite(RIGHT_MOTOR_PIN, abs(rightSpeed)); // 设置右轮PWM占空比 digitalWrite(RIGHT_MOTOR_PIN + 1, rightSpeed >= 0 ? HIGH : LOW); } } ``` 此段代码展示了简单的双直流电机控制系统架构,在实际项目里可能还需要加入PID调节环节提升性能表现。 --- #### ROS节点逻辑 接下来编写适用于ROS2环境内的Python脚本作为核心业务单元之一——即监听用户输入并将之转化为标准化格式后再转发出去供下一层级解读执行。 ```python import rclpy from geometry_msgs.msg import Twist import serial def main(args=None): rclpy.init(args=args) node = rclpy.create_node('car_controller') ser = serial.Serial('/dev/ttyUSB0', 115200) # 打开指定端口号的串行连接 def callback(msg): linear_x = msg.linear.x angular_z = msg.angular.z # 假设最大前进速度为1米每秒,旋转速率也为1弧度每秒 max_speed = 1.0 wheel_base = 0.3 # 米 vl = linear_x - angular_z * wheel_base / 2.0 vr = linear_x + angular_z * wheel_base / 2.0 cmd_str = f"{int(vl*max_speed)} {int(vr*max_speed)}\n" ser.write(cmd_str.encode()) sub = node.create_subscription(Twist, 'cmd_vel', callback, 10) try: while True: rclpy.spin_once(node) except KeyboardInterrupt: pass if __name__ == '__main__': main() ``` 上述例子定义了一个名为 `car_controller` 的节点实例对象,并设置了对其它进程所广播出来的 `/cmd_vel` 主题感兴趣的行为模式。每当接收到新的消息时都会触发回调函数内部的操作序列从而达到远程操控的目的。 --- #### 运动学计算 最后考虑一下有关物理层面的知识点补充说明。当涉及到具体的机械装置类型区分时候就需要引入额外参数参与运算过程之中去了比如说是阿克曼转向机构的话那么除了常规项之外还应该考虑到诸如轮胎倾角等因素的影响关系等等。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值