首页 > 其他分享 >ros micro-ros 自定义消息接口

ros micro-ros 自定义消息接口

时间:2024-07-01 15:45:26浏览次数:1  
标签:__ service 自定义 interfaces micro srv fishbot ros display

本节课最终效果是:通过自定义的服务接口控制开发板上的OLED显示器的内容。

ros2 service call /oled_control fishbot_interfaces/srv/OledControl "{px: 0, py: 0 ,data: 'oled control by service~'}"

 一、新建工程添加依赖
新建example14_custom_interface ,注意请不要将工程放置于文档目录下,因为自定义接口编译时目录拼接存在Bug

 修改platformio.ini

[env:featheresp32]
platform = espressif32
board = featheresp32
framework = arduino
lib_deps = 
    https://gitee.com/ohhuo/micro_ros_platformio.git
    adafruit/Adafruit SSD1306@^2.5.7

这里除了添加micro_ros库之外再添加oled驱动库。

二、添加自定义接口
添加自定义接口一共需要三步。

1.创建extra_packages文件夹并创建接口功能包

2.编译功能包(主要为了测试功能包是否正常)

3.删除.pio/libdeps/featheresp32/micro_ros_platformio/libmicroros文件夹,重新编译

2.1 创建功能包
在工程的主目录下创建extra_packages文件夹,接着在文件夹下创建fishbot_interfaces功能包

cd example14_custom_interface
mkdir extra_packages
cd extra_packages 
ros2 pkg create fishbot_interfaces

接着添加服务接口文件并修改CMakeLists.txt

文件extra_packages/fishbot_interfaces/srv/OledControl.srv

int32 px
int32 py
string data
---
int32 result

文件extra_packages/fishbot_interfaces/CMakeLists.txt

cmake_minimum_required(VERSION 3.5)
project(fishbot_interfaces)



if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
# uncomment the following section in order to fill in
# further dependencies manually.
# find_package(<dependency> REQUIRED)

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # the following line skips the linter which checks for copyrights
  # uncomment the line when a copyright and license is not present in all source files
  #set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # uncomment the line when this package is not in a git repo
  #set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()

find_package(rosidl_default_generators REQUIRED)

rosidl_generate_interfaces(${PROJECT_NAME}
  "srv/OledControl.srv"
 )

ament_package()

2.2 编译功能包

cd extra_packages/
colcon build

2.3 重新编译工程
编译前需要删除.pio/libdeps/featheresp32/micro_ros_platformio/libmicroros文件夹,使用Ctrl+Alt+B重新重新编译工程。

三、编写代码
和两数相加服务相似的代码,只不过更换了接口并添加了OLED的驱动。

#include <Arduino.h>
#include <micro_ros_platformio.h>

#include <rcl/rcl.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>
#include <micro_ros_utilities/string_utilities.h>

#include "Wire.h"
#include <Adafruit_GFX.h>     // 加载Adafruit_GFX库
#include <Adafruit_SSD1306.h> // 加载Adafruit_SSD1306库

#include <fishbot_interfaces/srv/oled_control.h> // 添加接口

rclc_executor_t executor;
rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;
// 定义服务
rcl_service_t service;

// 服务请求和返回消息定义
fishbot_interfaces__srv__OledControl_Request req;
fishbot_interfaces__srv__OledControl_Response res;

Adafruit_SSD1306 display;

// 服务回调函数
void service_callback(const void *req, void *res)
{
  fishbot_interfaces__srv__OledControl_Request *req_in = (fishbot_interfaces__srv__OledControl_Request *)req;
  fishbot_interfaces__srv__OledControl_Response *res_in = (fishbot_interfaces__srv__OledControl_Response *)res;
  // 计算sum
  display.clearDisplay();                    // 清空屏幕
  display.setCursor(req_in->px, req_in->py); // 设置开始显示文字的坐标
  display.println(req_in->data.data);        // 输出的字符
  display.display();
  res_in->result = 0;
}

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);
  // 创建节点 hello_microros
  rclc_node_init_default(&node, "example14_interface", "", &support);
  // 使用默认配置创建服务
  rclc_service_init_default(&service, &node, ROSIDL_GET_SRV_TYPE_SUPPORT(fishbot_interfaces, srv, OledControl), "/oled_control");
  // 创建执行器
  rclc_executor_init(&executor, &support.context, 1, &allocator);
  // 执行器添加服务
  rclc_executor_add_service(&executor, &service, &req, &res, service_callback);
  // 重要,为string类型消息分配空间
  req.data = micro_ros_string_utilities_init_with_size(100);

  /*========================OLED初始化====================================*/
  Wire.begin(18, 19);
  display = Adafruit_SSD1306(128, 64, &Wire);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // 设置OLED的I2C地址
  display.clearDisplay();                    // 清空屏幕
  display.setTextSize(1);                    // 设置字体大小
  display.setCursor(0, 0);                   // 设置开始显示文字的坐标
  display.setTextColor(SSD1306_WHITE);       // 设置字体颜色
  display.println("hello fishros!");         // 输出的字符
  display.display();
}

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

四、代码讲解
这里对新增的几行主要代码进行讲解

#include <micro_ros_utilities/string_utilities.h> 添加string工具类
 req.data = micro_ros_string_utilities_init_with_size(100); 使用string类型内存分配工具为data分配100字节e的空间
主要就是这两部分,值得注意的是,如果不提前为string类型的数据分配内容空间,最终会导致无法正常接收数据。

五、下载测试
5.1 编译下载
连接开发板,编译下载。

 5.2 启动Agent
接着打开终端启动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

点击下RST按钮,重启开发板,正常可以看到下图内容

 5.3 查看是否连通
接着打开终端查看节点和话题

ros2 node list
ros2 service list

 4.4 测试控制
进入extra_packages,source环境

source install/setup.bash

显示nihao

ros2 service call /oled_control fishbot_interfaces/srv/OledControl "{px: 0, py: 0 , data: 'nihao'}"

 

ros2 service call /oled_control fishbot_interfaces/srv/OledControl "{px: 0, py: 0 ,data: 'oled control by service~'}"

 

六、总结
本节通过使用自定义服务接口控制oled显示的例程,学习了如何在工程中添加自己的功能包和接口文件。下一节我们将学习如何让开发板的时间和上位机的时间进行同步。

 



标签:__,service,自定义,interfaces,micro,srv,fishbot,ros,display
From: https://www.cnblogs.com/ai-ldj/p/18278169

相关文章

  • 使用 ROS2的多机器人探索
    原文链接:https://www.youtube.com/watch?v=J0RZP_xJ3XA ThisvideoshowsademonstrationoftheSOSproject,dedicatedtoforestfiredetectionusingafleetofrobots.Severalimportantissuesareaddressed.这段视频展示了SOS项目的演示,该项目致力于使用机器人......
  • QT 使用Q_PLUGIN_METADATA实现自定义插件
    1.创建一个继承自QObject的类,并在类的实现文件中使用Q_PLUGIN_METADATA宏定义插件的元数据信息。这个宏通常包含插件的元数据,如插件的标识符、版本号等。2.在插件项目的.pro文件中添加QT += core gui widgets以确保能够使用Qt的相关功能。3.在主应用程序中使用QPluginLoade......
  • 最新AIGC系统源码-ChatGPT商业版系统源码,自定义ChatGPT指令Promp提示词,AI绘画系统,AI换
    目录一、前言系统文档二、系统演示核心AI能力系统快速体验三、系统功能模块3.1AI全模型支持/插件系统AI模型提问文档分析​识图理解能力3.2GPts应用3.2.1GPTs应用3.2.2GPTs工作台3.2.3自定义创建Promp指令预设应用3.3AI专业绘画3.3.1文生图/图生图(垫图)......
  • Dubbo 如何自定义协议为业务通信带来扩展
    Solomon_肖哥弹架构跟大家“弹弹”Dubbo自定义协议扩展欢迎点赞,收藏,关注。关注本人的公众号Solomon肖哥弹架构获取更多精彩内容Dubbo自定义协议扩展1、扩展说明RPC协议扩展,封装远程调用细节。契约:当用户调用refer()所返回的Invoker对象的invoke()方法......
  • SpringBoot自定义注解实现接口幂等
    一、前言接口幂等就是对一个接口执行重复的多次请求,与一次请求所产生的结果是相同的。对数据库的查询和删除是天然幂等的,更新操作在大多数场景下也是天然幂等。插入大多数情况下都是非幂等的,除非利用数据库的唯一索引来保证数据不会重复保存。二、为什么需要幂等1.超时重试......
  • 全网最适合入门的面向对象编程教程:06 类和对象的Python实现-自定义类的数据封装
    全网最适合入门的面向对象编程教程:06类和对象的Python实现-自定义类的数据封装摘要:本文我们主要介绍了数据封装的基本概念和特性,如何设置自定义类的私有属性和私有方法,protect属性的概念和特点。往期推荐:学嵌入式的你,还不会面向对象??!全网最适合入门的面向对象编程教程:00......
  • 53、Flink 测试工具测试用户自定义函数详解
    1.测试用户自定义函数a)单元测试无状态、无时间限制的UDF示例:无状态的MapFunction。publicclassIncrementMapFunctionimplementsMapFunction<Long,Long>{@OverridepublicLongmap(Longrecord)throwsException{returnrecord+1;}......
  • Cesium 实战 - 自定义纹理材质系列之 - 涟漪效果
    Cesium实战-自定义纹理材质系列之-涟漪效果核心代码完整代码在线示例Cesium给实体对象(Entity)提供了很多实用的样式,基本满足普通项目需求;但是作为WebGL引擎,肯定不够丰富,尤其是动态效果样式。对于实体对象(Entity),可以通过自定义材质,实现各种动态效果,虽......
  • 基于 ROS 的 Terraform 托管服务轻松部署文本转语音系统 ChatTTS
    介绍ChatTTS是专门为对话场景设计的文本转语音模型,例如LLM助手对话任务。它支持英文和中文两种语言。最大的模型使用了10万小时以上的中英文数据进行训练。ChatTTSwebUI&API为ChatTTS提供了网页界面和API服务。资源编排服务(ResourceOrchestrationService,ROS)是阿里云提......
  • 使用MicroBlaze的Boot Loader的注意事项
    AMD为MicroBlaze提供BootLoader,比如SRECBootLoader。它能将代码从QSPIFlash搬移到目标存储器(多半是DRAM)运行,使MicroBlaze运行大程序成为可能。如果MicroBlaze的BlockDesign设计有问题,比如BlockDesign设计中把DRAM链接到了DP(外设)端口,DRAM不能正常运行程序,也会导致BootLoade......