热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Vector数组类型在ROS开发中的用法小结

目录前言数组类型在不同消息类型中的定义在ROS消息中的定义在C中定义数组vector数组的一些常用操作基本操作求数组的最值遍历数组排序数组查找数组注意前言ROS系统的一个显著优势




目录


  • 前言
  • 数组类型在不同消息类型中的定义
    • 在ROS消息中的定义
    • 在C++中定义数组

  • vector数组的一些常用操作
    • 基本操作
    • 求数组的最值
    • 遍历数组
    • 排序数组
    • 查找数组
    • 注意




前言

ROS系统的一个显著优势就是分布式和灵活性,用户可以很方便自定义消息类型。在自动驾驶中,无论是传感器消息sensoe_msgs,还是导航消息nav_msgs等等几乎都离不开一个基本的结构:vector数组。尤其是在SLAM中,在处理雷达消息更是必不可少的操作。所以把vector理解透彻对于ROS开发还是非常重要的。

接下来的内容以C++语言为主,python语言是类似的,但是语法可能稍有不同。(PS:对于搞自动驾驶的同学,还是强烈推荐用C++开发,原因无他,C++快!!!在自动驾驶领域,处理速度是决定性的一个因素)


数组类型在不同消息类型中的定义

在ROS消息中的定义

ROS常用的消息分别是msg、srv、action,分别对应于topic话题、service服务、action动作三种通信模式。对于这三种数据类型,数组的定义格式都是一样的:

DateType[] name
举例:
msg消息sensor_msgs/LaserScan.msg

[std_msgs/Header] header
float32 angle_min
float32 angle_max
float32 angle_increment
float32 time_increment
float32 scan_time
float32 range_min
float32 range_max
float32[] ranges
float32[] intensities

这里ranges和intensities都是float32类型的数组

自定义srv消息

uint64 path_id #路径id
---
geometry_msgs/Pose2D[] path
geometry_msgs/Pose2D[] waypoints

自定义action消息

---
uint64 path_id #当前路径id
geometry_msgs/Pose2D[] path #所有路径点位姿,包括巡航点
geometry_msgs/Pose2D[] waypoints #巡航点位姿
bool success # 储存成功为true,否则为false
string message # error messages
---
uint64 path_id #当前路径id
geometry_msgs/Pose2D[] path_record #已经采样的路径点
geometry_msgs/Pose2D[] waypoints_record #已经采样的巡航点位姿

在C++中定义数组

使用它时需要包含头文件: #include
其构造函数为:

vector();
vector( size_type num, const TYPE &val );
vector( const vector &from );
vector( input_iterator start, input_iterator end );

举例:

vector a; //无参数 - 构造一个空的vector,
vector a(10); //定义了10个整型元素的向量(尖括号中为元素类型名,它可以是任何合法的数据类型),但没有给出初值,其值是不确定的。
vector a(10,1); //定义了10个整型元素的向量,且给出每个元素的初值为1
vector a(b); //用b向量来创建a向量,整体复制性赋值, 拷贝构造
vector v3=a ; //移动构造
vector a(b.begin(),b.begin+3); //定义了a值为b中第0个到第2个(共3个)元素
int b[7]={1,2,3,4,5,9,8};
vector a(b,b+6); //从数组中获得初值,b[0]~b[5]

vector数组的一些常用操作

基本操作

(1)a.assign(b.begin(), b.begin()+3); //b为向量,将b的0~2个元素构成的向量赋给a
(2)a.assign(4,2); //是a只含4个元素,且每个元素为2
(3)a.back(); //返回a的最后一个元素
(4)a.front(); //返回a的第一个元素
(5)a[i]; //返回a的第i个元素,当且仅当a[i]存在2013-12-07
(6)a.clear(); //清空a中的元素
(7)a.empty(); //判断a是否为空,空则返回ture,不空则返回false
(8)a.pop_back(); //删除a向量的最后一个元素
(9)a.erase(a.begin()+1, a.begin()+3); //删除a中第1个(从第0个算起)到第2个元素,也就是说删除的元素从a.begin()+1算起(包括它)一直到a.begin()+3(不包括它)
(10)a.push_back(5); //在a的最后一个向量后插入一个元素,其值为5
(11)a.insert(a.begin()+1, 5); //在a的第1个元素(从第0个算起)的位置插入数值5,如a为1,2,3,4,插入元素后为1,5,2,3,4
(12)a.insert(a.begin()+1, 3,5); //在a的第1个元素(从第0个算起)的位置插入3个数,其值都为5
(13)a.insert(a.begin()+1,b+3, b+6); //b为数组,在a的第1个元素(从第0个算起)的位置插入b的第3个元素到第5个元素(不包括b+6),如b为1,2,3,4,5,9,8,插入元素后为1,4,5,9,2,3,4,5,9,8
(14)a.size(); //返回a中元素的个数;
(15)a.capacity(); //返回a在内存中总共可以容纳的元素个数
(16)a.resize(10); //将a的现有元素个数调至10个,多则删,少则补,其值随机
(17)a.resize(10, 2); //将a的现有元素个数调至10个,多则删,少则补,其值为2
(18)a.reserve(100); //将a的容量(capacity)扩充至100,也就是说现在测试a.capacity();的时候返回值是100.这种操作只有在需要给a添加大量数据的时候才显得有意义,因为这将避免内存多次容量扩充操作(当a的容量不足时电脑会自动扩容,当然这必然降低性能)
(19)a.swap(b); //b为向量,将a中的元素和b中的元素进行整体性交换
(20)a.begin(); // 返回指向容器第一个元素的迭代器
(21)a.end(); // 返回指向容器最后一个元素的迭代器
&#xff08;22&#xff09;a&#61;&#61;b; //b为向量&#xff0c;向量的比较操作还有!&#61;,>&#61;,<&#61;,>,<
(23) reverse(a.begin(),a.end()); //对a中的从a.begin()&#xff08;包括它&#xff09;到a.end()&#xff08;不包括它&#xff09;的元素倒置&#xff0c;但不排列&#xff0c;如a中元素为1,3,2,4,倒置后为4,2,3,1
&#xff08;24&#xff09;copy(a.begin(),a.end(),b.begin()&#43;1); //把a中的从a.begin()&#xff08;包括它&#xff09;到a.end()&#xff08;不包括它&#xff09;的元素复制到b中&#xff0c;从b.begin()&#43;1的位置&#xff08;包括它&#xff09;开 始复制&#xff0c;覆盖掉原有元素

求数组的最值

可以用max_element&#xff08;&#xff09;及min_element&#xff08;&#xff09;函数&#xff0c;二者返回的都是迭代器或指针。

需要加入头文件&#xff1a;#include
1.求数组的最大值或最小值

1&#xff09;vector容器

vector v;
最大值&#xff1a;int maxValue &#61; *max_element(v.begin(),v.end());
最小值&#xff1a;int minValue &#61; *min_element(v.begin(),v.end());

2&#xff09;普通数组

a[]&#61;{1,2,3,4,5,6};
最大值&#xff1a;int maxValue &#61; *max_element(a,a&#43;6);
最小值&#xff1a;int minValue &#61; *min_element(a,a&#43;6);

2.求数组最大值最小值对应的下标

1&#xff09;vector容器

vector v;
最大值下标&#xff1a;int maxPosition &#61; max_element(v.begin(),v.end()) - v.begin();
最小值下标&#xff1a;int minPosition &#61; min_element(v.begin(),v.end()) - v.begin();

2&#xff09;普通数组


最大值下标&#xff1a;int maxPosition &#61; max_element(a,a&#43;6) - a;
最小值下标&#xff1a;int minPosition &#61; min_element(a,a&#43;6) - a;

注意&#xff1a;返回的是第一个最大&#xff08;小&#xff09;元素的位置。


遍历数组

1.
struct Point
{
double x;
double y;
Point()
{
x &#61; 0;
y &#61; 0;
}
};
vector m_testPoint;
//第一种遍历方式&#xff0c;下标
cout <<"第一种遍历方式&#xff0c;下标访问" < for (int i &#61; 0; i {

cout < }

//第二种遍历方式&#xff0c;迭代器
cout <<"第二种遍历方式&#xff0c;迭代器访问" < for (vector::iterator iter &#61; m_testPoint.begin(); iter !&#61; m_testPoint.end(); iter&#43;&#43;)
{
cout <<(*iter).x <<" " <<(*iter).y < }

//第三种遍历方式&#xff0c;auto关键字
cout <<"C&#43;&#43;11,第三种遍历方式&#xff0c;auto关键字" < for (auto iter &#61; m_testPoint.begin(); iter !&#61; m_testPoint.end(); iter&#43;&#43;)
{
cout <<(*iter).x <<" " <<(*iter).y < }

//第四种遍历方式&#xff0c;auto关键字的另一种方式
cout <<"C&#43;&#43;11,第四种遍历方式&#xff0c;auto关键字" < for (auto i : m_testPoint)
{
cout < }

排序数组

sort(a.begin(),a.end()); //对a中的从a.begin()&#xff08;包括它&#xff09;到a.end()&#xff08;不包括它&#xff09;的元素进行从小到大排列

查找数组

find(a.begin(),a.end(),10); //在a中的从a.begin()&#xff08;包括它&#xff09;到a.end()&#xff08;不包括它&#xff09;的元素中查找10&#xff0c;若存在返回其在向量中的位置

注意

C&#43;&#43;11版本以后建议优先使用emplace_back()来代替push_back()。因为emplace_back能通过参数构造对象&#xff0c;不需要拷贝或者移动内存&#xff0c;相比push_back能更好地避免内存的拷贝与移动&#xff0c;使容器插入元素的性能得到进一步提升。







推荐阅读
  • 本文详细探讨了HTML表单中GET和POST请求的区别,包括它们的工作原理、数据传输方式、安全性及适用场景。同时,通过实例展示了如何在Servlet中处理这两种请求。 ... [详细]
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
  • 本文深入探讨了HTTP请求和响应对象的使用,详细介绍了如何通过响应对象向客户端发送数据、处理中文乱码问题以及常见的HTTP状态码。此外,还涵盖了文件下载、请求重定向、请求转发等高级功能。 ... [详细]
  • 本文介绍了如何使用 Spring Boot DevTools 实现应用程序在开发过程中自动重启。这一特性显著提高了开发效率,特别是在集成开发环境(IDE)中工作时,能够提供快速的反馈循环。默认情况下,DevTools 会监控类路径上的文件变化,并根据需要触发应用重启。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 本文详细探讨了JDBC(Java数据库连接)的内部机制,重点分析其作为服务提供者接口(SPI)框架的应用。通过类图和代码示例,展示了JDBC如何注册驱动程序、建立数据库连接以及执行SQL查询的过程。 ... [详细]
  • 本文详细介绍了网络存储技术的基本概念、分类及应用场景。通过分析直连式存储(DAS)、网络附加存储(NAS)和存储区域网络(SAN)的特点,帮助读者理解不同存储方式的优势与局限性。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 本文详细介绍如何使用Samba软件配置CIFS文件共享服务,涵盖安装、配置、权限管理及多用户挂载等关键步骤。通过具体示例和命令行操作,帮助读者快速搭建并优化Samba服务器。 ... [详细]
  • 作为一名专业的Web前端工程师,掌握HTML和CSS的命名规范是至关重要的。良好的命名习惯不仅有助于提高代码的可读性和维护性,还能促进团队协作。本文将详细介绍Web前端开发中常用的HTML和CSS命名规范,并提供实用的建议。 ... [详细]
author-avatar
小艾6456
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有