利用ros实现单片机通讯(转载)

我觉得如果使用这个人的micro_ros通信协议,就不用再去Ubuntu或者Windows上面自己写驱动程序了,

利用micro_ros实现esp32与ros2的通讯

Tianci

Tianci

天津大学 工学博士

参考:https://github.com/micro-ROS/micro_ros_arduino

https://blog.csdn.net/ZhangRelay/article/details/101394537


  • micro_ros可以理解为一个运行在嵌入式平台的轻量级ros,其好处是建立了一套上位机平台(主要运行ubuntu+ros)与下位机平台(MCU)的通讯机制,包括串口、UDP、wifi等,省去了我们编写通讯协议的烦恼。
  • 这套通讯机制最大的好处是可以将下位机平台(MCU)当作ros中的一个Node,实现topic的发布、订阅,以及service、action等等。可以说是无缝兼容ros。
  • 个人粗浅的理解,ros最大的方便就是提供了一个基于Node的分布式通讯机制。

本文所用安装环境:

  • 上位机:旭日x3派 (ros2 foxy+ubuntu 20.04)
  • 下位机:M5stack Atom Lite(esp32 core)

0. micro_ros与micro_ros_arduino的安装

参考我之前写的一篇记录micro_ros配置记录 - 知乎

特别注意:

  • 2GB内存的旭日x3派开启swap,否则micro_ros_agent的build过程容易内存不足;
  • 网络环境务必能够通畅无阻的访问github,否则大概率失败!

1. 下位机配置

1.1 arduino支持包安装

我这里使用的下位机是M5stack Atom Lite,其核心是esp32,但我用arduino框架进行开发。

理论上,所有支持arduino开发的嵌入式平台应该都可以。

注意:务必安装自己嵌入式平台对应的arduino支持包。

正确安装M5stack支持包后,在开发板管理中应该出现M5 stack相关的信息。

image-20220716210240849

1.2 下位机代码

#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)));
}

1.3 代码解析

  • 代码基于micro_ros_arduino的示例代码micro-ros_publisher,对其进行简单修改。
  • ros2中turtle接收的msg类型为twist,所以首先添加twist头文件,并定义msg类型为twist
 #include <geometry_msgs/msg/twist.h>  //changed!    
 geometry_msgs__msg__Twist msg; //changed!-->modify msg type <twist__struct.h>
  • 将msg中的变量初始化为0
// 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;
  • 修改发布的topic的名字,修改为turtle1/cmd_vel。
  • 这一topic name要与ros2中turtlesim接收的topic name一致
// 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++;    
  }  
  }
  • 修改LED灯的管脚号(非必须)

2. 上位机配置

将下位机代码烧录后,将下位机通过串口连接上位机,这里我使用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
  • 首先提升串口读写权限(确保自己的串口是ttyUSB0,因硬件而异)
sudo chmod -R 777 /dev/ttyUSB0
  • 开启micro_agent
ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyUSB0
  • 按下下位机的复位键(特别注意,需要按下复位键)

image-20220717084958430

  • 重新开启一个终端,打开turtlesim_node
ros2 run turtlesim turtlesim_node
  • 此时可以看到turtle在运动了

image-20220717085058875

3. 其他

  • publisher示例代码的话题发布频率默认为1Hz,可以进行调整,10Hz没问题。但是想要100Hz往上就不行了
  • 需要更高的话题发布频率需要使用rclc_publisher_init_best_effort代替rclc_publisher_init_default
  • 但是best_effort的pub也需要best_effort的sub,所以当使用best_effort发布twist时,turtle不会运动,因为没有使用best_effort的sub来接收。关于这个可以参考:https://docs.ros.org/en/rolling/Concepts/About-Quality-of-Service-Settings.html#qos-compatibilities

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/175989.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

格式化名称节点,启动Hadoop

1.循环删除hadoop目录下的tmp文件&#xff0c;记住在hadoop目录下进行 rm tmp -rf 使用上述命令&#xff0c;hadoop目录下为&#xff1a; 2.格式化名称节点 # 格式化名称节点 ./bin/hdfs namenode -format 3.启动所有节点 ./sbin/start-all.sh 效果图&#xff1a; 4.查看节…

Java核心知识点整理大全8-笔记

Java核心知识点整理大全7-笔记-CSDN博客文章浏览阅读1.2k次&#xff0c;点赞27次&#xff0c;收藏26次。但是如果锁的竞争激烈&#xff0c;或者持有锁的线程需要长时间占用锁执行同步块&#xff0c;这时候就不适合 使用自旋锁了&#xff0c;因为自旋锁在获取锁前一直都是占用 c…

Servlet实现一个简单的表白墙网站

文章目录 前言效果展示事前准备HTML、CSS、JavaScript分别负责哪些HTML和CSS构架出页面的基本结构和样式JavaScript 实现行为和交互实现服务器端的业务代码整理pom.xmlweb.xmlmessageWall.htmlMessageServlet.java 前言 前面我们学习了 Java 中知名的 HTTP 服务器 tomcat 的安…

电脑盘符错乱,C盘变成D盘怎么办?

在一些特殊情况下&#xff0c;磁盘盘符会出现错乱&#xff0c;C盘可能会变成D盘。那么&#xff0c;这该怎么办呢&#xff1f;下面我们就来了解一下。 通过磁盘管理更改盘符 磁盘管理是Windows自带的工具&#xff0c;它位于“计算机管理”的控制台中。管理硬盘及其所包含的卷或…

Word隐藏批注知识分享,快速提升工作效率!

“请问大家&#xff0c;word里的批注应该怎么隐藏呢&#xff1f;有没有什么简单的方法可以将批注隐藏的呀&#xff1f;感谢感谢&#xff01;” Word中的批注功能在文档编辑中起着重要的作用&#xff0c;但有时为了保护文档的隐私和保密性&#xff0c;我们需要隐藏批注。 Word隐…

uboot移植-野火imx6ull

uboot移植及LCD和网络驱动设置 环境&#xff1a; Ubuntu 20.04 野火imx6ull pro开发板 tftp服务的搭建 IMX6ULL开发板参考的是NXP官方的I.MX6ULL EVK开发板做的硬件。 Linux的移植要复杂的多&#xff0c;在移植Linux之前我们需要先移植一个 bootloader 代码&#xff0c;这…

寄存器、缓存、内存之间的关系和区别

https://blog.csdn.net/m0_46761060/article/details/124689209 目录 关系1、寄存器2、缓存&#xff08;Cache&#xff09; 2.1、寄存器和缓存的区别2.2、一级缓存和二级缓存3、内存 3.1、只读存储器 ROM&#xff08;Read Only Memory&#xff09;3.2、随机存储器 RAM&#xf…

什么是凸函数

假设函数是定义在某个向量空间的凸子集上的实值函数&#xff0c;并且&#xff0c;如果对于中的任何两个向量和&#xff0c;都满足&#xff1a; 则称为上的凸函数

ESP32 Arduino实战Web篇-使用 WebSocket 创建 ESP32 Web 服务器

本文将详细介绍如何使用 WebSocket 创建 ESP32 Web 服务器,解释WebSocket原理与搭建步骤,并附超详细的代码解释 假设我们需要创建一个使用 ESP32 通过 WiFi 控制灯泡的项目。实现非常简单:我们将 ESP32 设置为软 AP 或 STA 模式,使其能够提供一个网页,显示灯开关的状态为…

计数排序+桶排序 详讲(思路+图解+代码详解)

文章目录 计数排序和桶排序一、计数排序概念&#xff1a;写法一&#xff1a;写法二&#xff1a; 二、桶排序概念代码 计数排序和桶排序 一、计数排序 时间复杂度&#xff1a;空间复杂度&#xff1a;稳定性&#xff1a;稳定 概念&#xff1a; 非基于比较的排序 计数排序又称为…

【Pytorch】Visualization of Fature Maps(2)

学习参考来自 使用CNN在MNIST上实现简单的攻击样本https://github.com/wmn7/ML_Practice/blob/master/2019_06_03/CNN_MNIST%E5%8F%AF%E8%A7%86%E5%8C%96.ipynb 文章目录 在 MNIST 上实现简单的攻击样本1 训练一个数字分类网络2 控制输出的概率, 看输入是什么3 让正确的图片分…

Visual Studio连接unity编辑器_unity基础开发教程

Visual Studio连接unity编辑器 问题描述解决方法意外情况 问题描述 当我们在unity编辑器中打开C#脚本的时候发现Visual Studio没有连接unity编辑器&#xff0c;在编写代码的时候也没有unity关键字的提醒。 简单来说就是敲代码没有代码提示。 解决方法 这时候需要在unity中进行…

【Pytorch】Visualization of Feature Maps(1)

学习参考来自 CNN可视化Convolutional Featureshttps://github.com/wmn7/ML_Practice/blob/master/2019_05_27/filter_visualizer.ipynb 文章目录 filter 的激活值 filter 的激活值 原理&#xff1a;找一张图片&#xff0c;使得某个 layer 的 filter 的激活值最大&#xff0c…

限时开发、码力全开、2w奖金!AGI Hackathon等你挑战!

AGI时代&#xff0c;我们已不再满足于简单的产品开发&#xff0c;与大模型结合的无限想象力&#xff0c;成为开发者们新的追求。 你有能力将想法转化为现实吗&#xff1f;你有勇气接受挑战&#xff0c;创造全新的AI应用吗&#xff1f; 如果你有热情&#xff0c;有信心&#x…

Git 教程

目录 Git 与 SVN 区别 Git 快速入门 学习目录 git简明指南 Git 安装配置 Git 工作流程、工作区、暂存区和版本库 Git 创建仓库 Git 基本操作 Git 分支管理 Git 查看提交历史 Git 标签 Git 远程仓库(Github) Git 服务器搭建 Git 是一个开源的分布式版本控…

909-2014-T1

文章目录 1.原题2.算法思想3.关键代码4.完整代码5.运行结果 1.原题 为带表头的单链表类Chain编写一个成员函数Reverse&#xff0c;该函数对链表进行逆序操作&#xff08;将链表中的结点按与原序相反的顺序连接&#xff09;&#xff0c;要求逆序操作就地进行&#xff0c;不分配…

MySQL - 4种基本索引、聚簇索引和非聚索引、索引失效情况

目录 一、索引 1.1、简单介绍 1.2、索引的分类 1.2.1、主键索引 1.2.2、单值索引&#xff08;单列索引、普通索引&#xff09; 1.2.3、唯一索引 1.2.4、复合索引 1.2.5、复合索引经典问题 1.3、索引原理 1.3.1、主键自动排序 1.3.2、索引的底层原理 1.3.3、B 树和 B…

简单几步,借助Aapose.Cells将 Excel XLS 转换为PPT

数据呈现是商业和学术工作的一个重要方面。通常&#xff0c;您需要将数据从一种格式转换为另一种格式&#xff0c;以创建信息丰富且具有视觉吸引力的演示文稿。当您需要在幻灯片上呈现工作表数据时&#xff0c;需要从 Excel XLS 转换为 PowerPoint 演示文稿。在这篇博文中&…

新能源充电桩工业4G路由器应用,推动绿色出行,响应环保理念

在智慧城市环保事业发展领域&#xff0c;新能源技术应用成熟&#xff0c;物联网技术越来越广泛&#xff0c;充电桩物联网成为了智慧城市建设的热门应用。充电桩作为新能源汽车的重要配套设施&#xff0c;对于节能减排和推动环保理念可持续发展具有重要意义。而工业4G路由器作为…

数环通对企业销售业务流程(O2C)的成熟度模型分享

保持紧密的客户关系&#xff0c;给客户留下良好的第一印象至关重要&#xff0c;而从下单到顺利履约是实现这一目标的最重要一环。 客户在做出购买决策后往往在最开始是充满了正向情绪&#xff08;例如兴奋、期待&#xff09;&#xff0c;但随着时间的推移&#xff0c;焦虑感会持…