当前位置: 首页 > news >正文

micro-ROS中对消息的内存管理

文章目录

  • 1.背景
  • 2.答案
    • 2.1.基本类型及其数组,不需要
    • 2.1.序列类型(复合类型、复合序列类型),需要
  • 3.内存申请方法
    • 3.1.手动申请(Manual allocation)
    • 3.1.工具辅助(micro-ROS utilities)
      • 3.1.1.规则的定义
      • 3.1.2.规则的使用

1.背景

我在之前的一篇文章【在VSCode下利用PlateFormIO开发Arduino的MicroROS遇到的一些问题】中的第10点中,提到一个问题:为啥在使用自定义消息类型时,有时候需要调用 micro_ros_utilities_create_message_memory 函数来对消息对象进行内存申请,而有时候不用呢?

2.答案

其实答案就在这篇官方的指导/说明文章中:【Handling messages memory in micro-ROS】

是否需要对消息类型进行内存申请,取决于消息的成员类型。

2.1.基本类型及其数组,不需要

假如你的消息的成员类型是基本类型(Basic type)及其数组类型(Array type),比如bool、byte、char、float32,bool[n]、byte[n]、char[n]、float32[n]等等,那就不用额外进行内存申请的操作,因为这些基本类型在实例化时就已经明确了空间大小,系统直接帮忙分配好了内存。

bool bool_test
byte byte_test
char char_test
float32 float32_test
float64 double_test
int8 int8_test
uint8 uint8_test
int16 int16_test
uint16 uint16_test
int32 int32_test
uint32 uint32_test
int64 int64_test
uint64 uint64_test

2.1.序列类型(复合类型、复合序列类型),需要

但是,假如消息的成员类型为:序列类型(Sequence type)、包含序列的复合类型(Compound type)、复合序列类型(Sequences of compound types),那就需要手动申请内存空间了。当然,假如复合类型中的成员全是基本类型,那也不用手动申请。
上面提到的这些类型,之所以需要人为去申请内存,原因很简单:系统不知道你要多大的空间。
就拿int32的序列int32[](注意,这个不是数组类型,中括号中间没有具体的数值)来说,在micro-ROS中,该类型经过解析后,得到的是这样一个结构体:

typedef struct rosidl_runtime_c__int32__Sequence
{int32_t* data;    /* The pointer to an array of int32 */size_t size;      /* The number of valid items in data */size_t capacity;  /* The number of allocated items in data */
} rosidl_runtime_c__int32__Sequence;

由于size、capacity都是未知的,那么系统如何知道要申请多大的内存空间并把指针值赋予data呢?
因此需要程序员自己手动申请并赋值一下。(这里解释一下上述结构体中的size、capacity的区别,类比电池的话,size表示剩余电量/可用电量,capacity表示电池总容量。这样设计,估计是为了在实例化一次这个对象后,能够对这个对象反复利用)

3.内存申请方法

在这个【Handling messages memory in micro-ROS】文章中提到,在micro-ROS中处理消息的内存有两种方式:手动申请(Manual allocation)、辅助申请(micro-ROS utilities)。

3.1.手动申请(Manual allocation)

这个就是要求对数据结构的各个成员进行数据填充、内存分配。比如对上面的rosidl_runtime_c__int32__Sequence类型,可以这样子初始化:

rosidl_runtime_c__int32__Sequence values;values.capacity = 100;
values.data = (int32_t*) malloc(mymsg.values.capacity * sizeof(int32_t));
values.size = 0;

这样子操作比较繁琐,更好的是下面的方法。

3.1.工具辅助(micro-ROS utilities)

在micro-ROS中,官方提供了一些函数及结构,可以让我们相对便捷地对消息类型进行内存管理。
这里看一下例子:

mypackage__msg__MyComplexType mymsg;static micro_ros_utilities_memory_conf_t conf = {0};micro_ros_utilities_memory_rule_t rules[] = {{"multiheaders", 4},{"multiheaders.frame_id", 60},{"name", 10}
};
conf.rules = rules;
conf.n_rules = sizeof(rules) / sizeof(rules[0]);// member named "values" of MyComplexType will have the default max_basic_type_sequence_capacitybool success = micro_ros_utilities_create_message_memory(ROSIDL_GET_MSG_TYPE_SUPPORT(mypackage, msg, MyComplexType),&mymsg,conf
);

其中,mypackage__msg__MyComplexType类型是这样子的:

typedef struct mypackage__msg__MyComplexType
{std_msgs__msg__Header__Sequence multiheaders;rosidl_runtime_c__int32__Sequence values;double duration;int8 coefficients[10];rosidl_runtime_c__String name;  // equal to rosidl_runtime_c__char__Sequence
} mypackage__msg__MyComplexType;

header的类型是这样的:

typedef struct std_msgs__msg__Header
{builtin_interfaces__msg__Time stamp;rosidl_runtime_c__String frame_id;
} std_msgs__msg__Header;

3.1.1.规则的定义

可以看到,针对mypackage__msg__MyComplexType的成员multiheaders,指定下面的内存申请规则:

...
micro_ros_utilities_memory_rule_t rules[] = {{"multiheaders", 4}, // 对序列进行长度(capacity)的申请{"multiheaders.frame_id", 60}, // frame_id是字符串,进行60字节的申请...
};
...

rule的具体的写法应该是

 {"对象成员名称",  Sequence的capacity大小}

在这里插入图片描述

需要注意的是,序列成员的成员可以直接写,而不用序列号,比如上面的"multiheaders.frame_id"就不用写成"multiheaders.data[0].frame_id"之类的。

另外,对于未在rules中指定的序列类型成员,会按照micro_ros_utilities_memory_conf_t的max_string_capacity、max_ros2_type_sequence_capacity、max_basic_type_sequence_capacity来进行申请,假如需要覆盖默认值micro_ros_utilities_memory_conf_default,可以这样操作:

static micro_ros_utilities_memory_conf_t conf = {0};conf.max_string_capacity = 50;
conf.max_ros2_type_sequence_capacity = 5;
conf.max_basic_type_sequence_capacity = 5;

3.1.2.规则的使用

定义好规则之后,当调用 micro_ros_utilities_create_message_memory 函数时,应该是对Sequence类型的capacity进行赋值,然后再根据此capacity进行实际内存的计算+申请。(可能会涉及递归过程?)
大概看一下源码,应该是的。具体实现过程有空再分析分析。
在这里插入图片描述


参考:
【Handling messages memory in micro-ROS】

相关文章:

micro-ROS中对消息的内存管理

文章目录 1.背景2.答案2.1.基本类型及其数组,不需要2.1.序列类型(复合类型、复合序列类型),需要 3.内存申请方法3.1.手动申请(Manual allocation)3.1.工具辅助(micro-ROS utilities)…...

Springboot中使用拦截器、过滤器、监听器

一、Servlet、Filter(过滤器)、 Listener(监听器)、Interceptor(拦截器) Javaweb三大组件:servlet、Filter(过滤器)、 Listener(监听器) Spring…...

代码随想录二刷day45

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、力扣70. 爬楼梯二、力扣322. 零钱兑换三、力扣279. 完全平方数 前言 一、力扣70. 爬楼梯 class Solution {public int climbStairs(int n) {int[] dp new…...

泊车功能专题介绍 ———— AVP系统基础数据交互内容

文章目录 系统架构系统功能描述云端子系统车辆子系统场端子系统用户APP 工作流程基础数据交互内容AVP 系统基础数据交互服务车/用户 - 云基础数据交互内容车位查询工作流程技术要求数据交互要求 车位预约工作流程技术要求数据交互要求 取消预约工作流程技术要求数据交互要求 泊…...

蓝桥杯每日一题2023.10.6

题目描述 门牌制作 - 蓝桥云课 (lanqiao.cn) 题目分析 #include<bits/stdc.h> using namespace std; int ans; int main() {for(int i 1; i < 2020; i ){int x i;while(x){int a x % 10;if(a 2)ans ;x / 10;}}cout << ans;return 0; } 题目描述 既约分数…...

7、【Qlib】【主要组件】Data Layer:数据框架与使用

7、【主要组件】Data Layer&#xff1a;数据框架与使用 简介数据准备Qlib 格式数据Qlib 格式数据集自动更新日频率数据将 CSV 格式转换为 Qlib 格式股票池&#xff08;市场&#xff09;多股票模式 数据API数据检索特征过滤器 数据加载器QlibDataLoaderStaticDataLoaderInterfac…...

Kubernetes安装部署 1

本文主要描述kubernetes的安装部署&#xff0c;kubernetes的安装部署主要包括三个关键组件&#xff0c;其中&#xff0c;包括kubeadm、kubelet、kubectl&#xff0c;这三个组件的功能描述如下所示&#xff1a; Kubeadm 用于启动与管理kubernetes集群 Kubelet 运行在所有集群的…...

在VS Code中优雅地编辑csv文件

文章目录 Rainbow csv转表格CSV to Tablecsv2tableCSV to Markdown Table Edit csv 下面这些插件对csv/tsv/psv都有着不错的支持&#xff0c;这几种格式的主要区别是分隔符不同。 功能入口/使用方法Rainbow csv按列赋色右键菜单CSV to Table转为ASCII表格指令CSV to Markdown …...

LCR 128.库存管理 I

​题目来源&#xff1a; leetcode题目&#xff0c;网址&#xff1a;LCR 128. 库存管理 I - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 数组可以分割成两段的升序连续子数组&#xff0c;找到两个子数组的开始元素并返回较小者即可。 解题代码&#xff1a; …...

eigen::Affine3d 转换

平移eigen::vector3d和四元数Eigen::Quaterniond 转 eigen::Affine3d Eigen::Vector3d t Eigen::Vector3d::Zero(); Eigen::Quaterniond q Eigen::Quaterniond ::Identity();Eigen::Affine3d affine3d t * q.toRotationMatrix(); Eigen::Matrix4d 转 eigen::Affine3d Eige…...

【Python从入门到进阶】38、selenium关于Chrome handless的基本使用

接上篇《37、selenium关于phantomjs的基本使用》 上一篇我们介绍了有关phantomjs的相关知识&#xff0c;但由于selenium已经放弃PhantomJS&#xff0c;本篇我们来学习Chrome的无头版浏览器Chrome Handless的使用。 一、Chrome Headless简介 Chrome Headless是一个无界面的浏览…...

给Python项目创建一个虚拟环境(enev)

给Python项目创建一个虚拟环境&#xff08;enev&#xff09; 为您的Python项目创建一个虚拟环境是一种良好的实践&#xff0c;可以隔离项目的依赖项&#xff0c;以确保它们不会干扰全局Python环境或其他项目。您可以使用venv模块来创建虚拟环境。以下是在Linux上创建虚拟环境的…...

【RK3588】YOLO V5在瑞芯微板子上部署问题记录汇总

YOLO V5训练模型部署到瑞芯微的板子上面&#xff0c;官方是有给出案例和转过详情的。并且也提供了Python版本的推理代码&#xff0c;以及C语言的代码。 但是&#xff0c;对于转换过程中的细节&#xff0c;哪些需要改&#xff1f;怎么改&#xff1f;如何改&#xff0c;和为什么…...

别人做的百度百科词条信息不全,如何更正自己的百度百科词条

很多人自己的百度百科词条是别人上传上去的&#xff0c;自己压根不知道&#xff0c;而且里面的信息内容要么不全&#xff0c;要么是有错漏的&#xff0c;但自己想要更正自己的百度百科词条又不知道如何更正&#xff0c;下面洛希爱做百科网和大家介绍一些百科经验知识。 首先百…...

[论文精读]U-Net: Convolutional Networks for BiomedicalImage Segmentation

论文原文&#xff1a;U-Net: Convolutional Networks for Biomedical Image Segmentation (arxiv.org) 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔…...

Godot Identifier “File“ not declared in the current scope.

解决方案&#xff1a; f FileAccess.open(savedir, FileAccess.READ)...

Java ORM Bee,多表关联更新

Bee V2.1.8 增加支持多表的update, insert, delete; 使用FK注解进行关联. 如果子实体没有用上FK声明的字段(即FK的字段没有值),则不执行,防止更新到多余记录 外键有一个没有设置时&#xff0c;跳过。 更多实例,请查看样例工程:https://gitee.com/automvc/bee-exam 或:h…...

Java 读取excel文件

导入&#xff1a; 先导入依赖&#xff1a; <!-- 文件上传 --> <dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpmime</artifactId><version>4.5.7</version> </dependency> <!-- JSON -…...

PageRank(上):数据分析 | 数据挖掘 | 十大算法之一

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者:秋无之地 🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据开发、数据分析等。 🐴欢迎小伙伴们点赞👍🏻、收藏⭐️、…...

吃鸡达人专享!提高战斗力,分享干货,查询装备皮肤,保护账号安全!

大家好&#xff01;作为专业吃鸡行家&#xff0c;我将为您带来一些热门话题和实用内容&#xff0c;帮助您提升游戏战斗力&#xff0c;分享顶级游戏作战干货&#xff0c;并提供便捷的作图工具和查询服务。让我们一起享受吃鸡的乐趣&#xff01; 首先&#xff0c;我要推荐一款绝地…...

3步实现手游PC级操控:QtScrcpy键鼠映射技术全解析

3步实现手游PC级操控&#xff1a;QtScrcpy键鼠映射技术全解析 【免费下载链接】QtScrcpy Android实时投屏软件&#xff0c;此应用程序提供USB(或通过TCP/IP)连接的Android设备的显示和控制。它不需要任何root访问权限 项目地址: https://gitcode.com/barry-ran/QtScrcpy …...

开源视觉模型推荐:GLM-4v-9B,高分辨率输入,中文OCR领先

开源视觉模型推荐&#xff1a;GLM-4v-9B&#xff0c;高分辨率输入&#xff0c;中文OCR领先 1. 引言 在当今多模态AI快速发展的时代&#xff0c;视觉-语言模型正成为技术前沿的热点。GLM-4v-9B作为智谱AI最新开源的90亿参数视觉-语言多模态模型&#xff0c;凭借其11201120高分…...

vLLM-v0.17.1效果展示:vLLM在中文古诗生成任务中的韵律保持能力

vLLM-v0.17.1效果展示&#xff1a;vLLM在中文古诗生成任务中的韵律保持能力 1. vLLM框架简介 vLLM是一个专为大型语言模型(LLM)设计的高性能推理和服务库&#xff0c;以其出色的速度和易用性著称。这个项目最初由加州大学伯克利分校的天空计算实验室开发&#xff0c;现在已经…...

北京大学钟亦武老师招收博士生、实习生

点击下方卡片&#xff0c;关注“CVer”公众号AI/CV重磅干货&#xff0c;第一时间送达冲刺今年春招、秋招和实习&#xff01;大家快加入2026年AI校招群&#xff01;赠送今年最大的80元优惠券&#xff0c;大家扫码下方二维码即可加群学习&#xff01;北京大学智能学院介绍&#x…...

深入TC397与TLF35584的SPI通信:从寄存器操作到汽车ECU低功耗状态管理实战

深入TC397与TLF35584的SPI通信&#xff1a;从寄存器操作到汽车ECU低功耗状态管理实战 在汽车电子领域&#xff0c;电源管理芯片的选择与配置直接关系到整车电子控制单元&#xff08;ECU&#xff09;的可靠性与能耗表现。英飞凌的TLF35584作为一款高集成度电源管理IC&#xff0c…...

泛微OA Ecology 安全补丁管理账号配置与实战

1. 泛微OA Ecology安全补丁管理账号配置详解 第一次接触泛微OA Ecology系统的安全补丁管理功能时&#xff0c;我完全没意识到这个看似简单的配置背后藏着这么多门道。直到有次系统被恶意攻击&#xff0c;才发现默认的管理账号存在安全隐患。今天就带大家彻底搞懂这个关键配置&a…...

云容笔谈·东方红颜影像生成系统与ComfyUI工作流集成:可视化节点式创作

云容笔谈东方红颜影像生成系统与ComfyUI工作流集成&#xff1a;可视化节点式创作 如果你是一位数字艺术家或者技术美术&#xff0c;可能常常面临这样的困境&#xff1a;你有一个绝佳的创意&#xff0c;比如想生成一幅融合了东方古典美学与现代光影的“红颜”肖像&#xff0c;但…...

Windows下OpenClaw安装指南:对接ollama GLM-4.7-Flash模型

Windows下OpenClaw安装指南&#xff1a;对接ollama GLM-4.7-Flash模型 1. 为什么选择OpenClaw GLM-4.7-Flash组合 作为一个长期在Windows环境下折腾AI工具的开发者&#xff0c;我一直在寻找一个既能保持本地数据隐私&#xff0c;又能灵活对接各类开源模型的自动化框架。Open…...

第4章 编码规范-4.1 命名规范

在Python中&#xff0c;变量、常量、模块、包、函数、类、对象、属性、方法和异常类都具有一定的命名规范。但是&#xff0c;这些命名规范都是通用性规范&#xff0c;而不是强制性规范&#xff0c;所以具体的命名规范还需要以开发项目的要求为主。&#xff08;1&#xff09;变量…...

【SpringBoot 】dynamic 动态数据源配置连接池(转)

前言 在复杂的业务场景中&#xff0c;我们经常需要使用多数据源来满足不同的数据访问需求。Dynamic Datasource 为我们提供了一种灵活切换不同数据源的解决方案。但是多数据源配置连接池 以及说明文档都是收费的。 本篇博文将详细介绍如何配置和优化 Dynamic Datasource 的连接…...