- 博客(186)
- 收藏
- 关注
原创 C++ boost::property_tree::read_json读取虚拟墙文件
json中含有一系列的线段起点和终点,我们的目标时是其提取出来。输入是一个json文件如下。
2024-06-26 11:15:56
372
1
原创 机器学习算法——适用于提取点云障碍物轮廓的聚类算法—costmap_convert(DBSCAN聚类算法)
最近在做项目过程中,我们注意到当考虑车体轮廓去进行全局路径规划(如混合A*算法),如果仅仅将障碍物点云数据中得每一个点只当成点,会造成较大的计算时间,如若将点云聚类成圆形 线型 多边形障碍物 会提高计算效率,这是其中一个原因,另一个原因是,我们需要知道障碍物的大小,障碍物大小程度决定了我们的动态避障的方法和策略。因此我根据costmap_conventer 进行了脱ROS处理,删除了一些暂时不用的逻辑,方便项目中使用。
2024-06-08 18:29:35
901
原创 机器人规划控制——工程化——心得日记-20240510
遇到一个特别有趣的问题,当然最后查出来原因也感觉比较纯,就是我们机器人在行进过程中,会当前要走的路径与周围障碍物发生了干涉检测即有碰撞风险,然后会请求全局规划,我们注意到计算的局部目标点一直在远处挪,突然某一贞,生了局部的路线,即全局的路线不是从起点开始的,而是从另外很远的地方开始,但终点是对的,这样全局规划的线是错误的,但是全局规划器返回的状态是success,那局部控制器就跟踪这个有问题的全局线,进而导致机器人撞到障碍物了。生成的全局路径初始2个坐标打印,然后重新复现,采集数据,并分析。
2024-05-10 22:15:07
676
原创 机器人规划算法——A*算法
我注意到,在计算相邻点的代价值时,使用 QuadraticCalculator::calculatePotential,生成的路径比较直,而使用PotentialCalculatorr::calculatePotential::calculatePotential计算的路径比较曲折。整个算法利用了两个邻居之间的相对代价来进行潜在值的更新,根据代价因子和相对代价的大小来决定更新策略,从而有效地平衡插值和单一邻居更新的权衡。接着计算每个邻居之间的相对代价dc,即tc和ta之间的差值。问题1:如何理解如下代码?
2024-04-11 19:06:24
704
原创 机器人运动——全局转车辆坐标下-坐标变换
在这个示例中,globalToLocal 函数接受全局坐标点和车辆的全局坐标以及朝向作为输入,并返回相对于车辆坐标系下的坐标。2.根据车辆的朝向 theta ,对偏移量进行旋转,以得到相对于车辆坐标系下的坐标。1.计算全局坐标点 (x1, y1) 相对于车辆的偏移量;
2024-04-10 08:22:32
379
原创 C++类 单例模式
类使用了一个单例模式,这意味着这个类只需要一个实例,并且提供了全局访问点来获取这个实例。这通常用于控制对一个类实例的访问,尤其是在创建实例代价昂贵或者需要严格控制实例数量的情况下。单例模式(Singleton Pattern)是一种设计模式,用于确保一个类只有一个实例,并提供一个全局访问点来获取该实例。在这个修正后的代码中,我们确保了构造函数和析构函数是私有的,并且提供了一个全局访问点来获取。方法返回类的唯一实例的引用,您可以使用该引用来访问和调用类的公有成员函数。在您的代码中,单例模式的实现确保了。
2024-04-02 10:05:25
829
1
原创 Linux系统中段错误信号sigsegv的捕获
但是,在某些情况下,我们希望能够捕获这个信号,并进行一些特定的处理,比如打印出错信息、记录日志或者进行资源清理等,而不是让程序立即退出。在上述代码中,为了简化,我们没有包含这部分内容,但在实际开发过程中,这是非常重要的一步。的错误,例如,确保指针在使用前已经被正确初始化,数组访问不超过其边界等。在信号处理函数中,我们可以进行错误处理,比如打印相关信息或者清理资源。在Linux系统中,当程序试图访问它没有权限访问的内存区域时,操作系统会发送一个。在上面的代码中,我们使用。在实际的应用中,处理。
2024-04-02 09:24:42
610
原创 机器人规划算法——基于A-star和CostMap膨胀地图的全局规划(附Github源码链接)
这段时间,笔者用c++写了一套机器人局部避障算法,并工程落地,机器人可以正常避障,避障所采用的技术方案是A*+TEB算法。并取得一定成果,后续还要针对复杂的场景继续优化。主要涉及到技术模块有:(1) costmap:代价地图模块,分为静态层和障碍物层以及膨胀层,静态层将读取地图信息并根据机器人内切半径进行膨胀,障碍物层是根据搭载的传感器检测到的障碍物点云并且以机器人内切圆半径进行膨胀。(2)全局规划器:这部分规划部分主要是A根据costmap规划一条路径。
2024-03-29 15:22:48
1155
2
原创 机器人干涉(碰撞)检测基础——Bresenham 直线算法
Bresenham 直线算法是一种画线算法,用于确定应选择的n维栅格中的点,以形成两点之间直线的近似值。它通常用于在位图图像中(例如在计算机屏幕上)绘制线图元,因为它仅使用整数加法、减法和位移位,所有这些在历史上常见的计算机体系结构中都是非常便宜的操作。它是一种增量误差算法,是计算机图形学领域最早开发的算法之一。称为中点圆算法的原始算法的扩展可用于绘制圆。虽然像Wu 算法这样的算法因为可以支持抗锯齿而在现代计算机图形学中也经常使用,但 Bresenham 线算法由于其速度和简单性仍然很重要。
2024-03-25 11:50:47
587
原创 机器人路径平滑——线性插值
请注意,这里的内插算法是一个简化示例,使用了线性插值来平滑路径上的点。实际应用中,你可以使用更复杂的算法,如B样条曲线、Catmull-Rom曲线等。这些算法可以根据需要,根据控制点和参数来计算平滑曲线。如果有任何进一步的问题,请随时提问。这段代码实现了一种简化的平滑曲线算法,使用线性插值来平滑给定路径上的点。这个内插点的坐标是前一个点、当前点和后一个点的坐标的平均值。对于每个点,我们考虑路径上的前一个点。蓝色是原始路径,红色是平滑后的曲线。中除了起始点和终止点之外的所有点。向量,用于存储平滑后的路径点。
2024-02-18 16:31:11
518
原创 机器人路径平滑——贝塞尔曲线
该函数使用了三阶贝塞尔曲线的公式,根据参数t(范围为0到1)、起始点p0、控制点p1和终止点p2,计算出贝塞尔曲线上的相应点的坐标。该函数通过遍历路径上的相邻三个点,将每两个点之间的线段使用贝塞尔曲线进行平滑。通过以上步骤,代码实现了使用贝塞尔曲线对给定的路径曲线进行平滑处理,得到了一条平滑的路径曲线。参数用于控制每两个路径点之间贝塞尔曲线的细分数,即将每段线段平滑成多少个小曲线段。函数计算出每个t值对应的贝塞尔曲线上的点,并将这些点存入一个新的向量中。向量中的路径点,即平滑后的路径曲线的坐标。
2024-02-18 14:52:36
1183
原创 valgrind being installed on Arm platform
2.在ARM的板子上运行valgrind, 程序出现valgrind Fatal error at startup: a function redirection的错误提示。查找了下,发现是因为libc或ld.so库进行过strip操作。直接安装一个debug版本的库就可以了。
2024-01-17 16:34:26
599
原创 C++ 代码优化—set(CMAKE_CXX_FLAGS_RELEASE “-O2“)
在对导航代码进行交叉编译的时候,由于线程占CPU资源过大,我在CMake中添加如下优化。交叉编译可以通过,但是在目标平台arm上运行报线程相关错误。程序正常运行,占用CPU资源也降下来了。
2024-01-02 19:05:29
746
原创 【将G2O库使用交叉编译移植到arm平台】
笔者用g2o来做teb,teb中cmake时要将/home/juchunyu/workspace/Navigation_system/cmake_modules/FindG2O.cmake 的下面几行注释掉。使用g2o时只需链接g2o_ext_csparse g2o_core g2o_csparse_extension g2o_stuff这几个库。1.将suitesparse文件夹中的CXSParse里的源码替换掉g2o的EXTERNAL文件夹中的csparse。在g2o根文件夹下执行下面的命令。
2023-12-28 16:45:58
1203
1
原创 C++ boost planner_cond_.wait(lock) 报错1225
在进入gdb后输入 bt,用bt命令查看backtrace以检查发生程序运行到哪里,来定位core dump的文件->行。通过这种方式,我们保证了唤醒的线程可以获得互斥量的所有权,并避免在没有所有权的情况下解锁互斥量导致的错误。在进入gdb后输入where并回车,就可以指出是在哪一行被Down掉,在哪个函数内,由谁调用等等。重新上锁互斥量,以便在下一次循环开始时可以正确地等待新的条件变量通知。等待条件变量的通知,并在等待之前释放锁。对象会自动重新获取互斥量的所有权,然后我们继续执行计划的操作。
2023-12-25 11:06:34
1042
原创 C++ 枚举的用法
语句根据不同的状态进行判断并输出相应的信息。在这个例子中,输出结果将为"Currently in clearing state。上述代码定义了一个枚举类型。
2023-12-21 15:11:37
518
原创 关于图像像素opencv行与列关系
(1)m4.cols表示m4矩阵的列数,对应图片像素的宽度。(2)m4.rows表示m4矩阵的行数,对应图片像素的高度。其中m4是一个矩阵,读取的图片就存在这个地方。
2023-12-18 14:32:14
817
原创 valgrind定位C++线程/内存等错误
Valgrind 由内核(core)以及基于内核的其他调试工具组成。内核类似于一个框架(framework),它模拟了一个 CPU 环境,并提供服务给其他工具;而其他工具则类似于插件 (plug-in),利用内核提供的服务完成各种特定的内存调试任务。Valgrind 是一套 Linux 下,开放源代码(GPL V2)的仿真调试工具的集合。
2023-12-18 14:12:59
453
原创 机器人导航地图——costmap局部地图滚动costmap_.updateOrigin理解
代价地图的一个参数,表示该代价地图的world坐标系原点(origin_x_, origin_y_)【**代价地图原点都在地图的左下角】**是否要随着机器人移动而改变。local_map是目标,它的宽度等于源中要复制的宽度cell_size_x,因为每栅格值一个字节,这个宽度也等于跨距。一是重新计算原点origin_x_/y_,方法是微调参数new_origin_x、new_origin_y,确保新原点坐标能被resolution_(0.05)整除。的实现,用于将源地图的一个区域拷贝到目标地图中。
2023-12-06 15:42:06
1799
原创 C++延时程序
函数获取的是 CPU 时间,不会导致线程或进程的真正休眠。要实现真正的睡眠功能,可以使用适当的跨平台库或操作系统提供的相关函数。输出了起始时间、当前时间和当前时间减去起始时间的差值,以观察程序的运行状态。,即当前时间减去起始时间小于等于指定的时间。头文件,以便使用标准输入输出和时间相关函数。函数来获取当前的CPU时间,进行延时操作。函数获取当前的 CPU 时间,将其赋值给。函数,该函数用于模拟程序暂停一段时间。函数来进行简单的时间控制,以及使用。参数,用于指定程序要休眠的时间。的函数,该函数接受一个。
2023-12-04 16:00:21
602
原创 C++高级用法—使用boost::shared_ptr来创建共享指针对象并保持了多态性的特性
这样,就可以使用基类的指针对象来操作派生类的对象,并且在运行时动态地选择适当的函数实现。这就是使用多态性的一种常见做法。本文我们将使用了boost::shared_ptr来创建共享指针对象,并且实现多态的功能。类型的指针进行使用。这就实现了多态性,即可以通过基类的指针来操作不同派生类的对象。(1)我们将上述代码文件命名为virtual.cpp。首先,我们创建了三个共享指针对象。类的子类,因此可以将它们作为。
2023-12-04 15:24:24
718
原创 机器人导航地图——Obstacle层的障碍物-Bresenham算法详细解释
作者在读源代码时,遇到了下述的代码void ObstacleLayer::raytraceFreespace,不是很好理解,有很多疑惑,于是打算对此部分进行详解,并记下笔记。////clearing_observation的origin_是传感器坐标,传入//得到传感器原点在地图上的坐标if (!ox, oy);return;//我们可以在内环之外预先计算地图的点。。。我们稍后需要这些//接下来的几个判断结构实际上做的主要工作就是不断迭代传感器原点和点云中的点的连线,
2023-12-01 15:17:25
1753
原创 C++类中运算符(operator())的重载
在函数体内,它将costmap_[offset]设置为value_,即将costmap中对应的单元格标记为指定的值。在这个例子中,MarkCell类重载了函数调用运算符operator(),当类的对象被调用时,就会调用这个重载的函数调用运算符。在函数调用运算符的实现中,接受了一个unsigned int类型的参数offset,表示要标记的单元格在costmap中的偏移量。这样,通过创建一个MarkCell对象,并将对象作为函数来调用,就可以将指定的单元格在costmap上进行标记。
2023-12-01 09:58:04
470
原创 机器人导航算法——Costmap地图ROS源码解析
costmap使用了一种分层地图的技术方案,即分别考虑障碍物层/膨胀层/静态障碍物层更新对应层的地图代价信息,然后再合并到主地图中,具体见我翻译的另一篇文章《costmap文献阅读—Layered Costmaps for Context-Sensitive Navigation以上就是costmap的介绍,后续会持续更新。。。。ReferenceCostmap文献阅读——Layered Costmaps for Context-Sensitive Navigation。
2023-11-29 13:48:08
2160
原创 机器人算法——costmap膨胀层InflationLayer
InflationLayer没有自身的栅格地图要维护,直接在主地图上进行操作,它根据膨胀参数设置用来膨胀的“参考矩阵”,并在主地图上从障碍物出发,不断传播更新,完成对整个地图障碍的膨胀。使用计算考察点和障碍物的距离,然后判断是否在膨胀半径内,如果是,则保存到nflation_cells_中用于下一次循环中。不断的从障碍物周围”上下左右“开始膨胀,并且根据参考矩阵去计算不同距离的栅格权重。这是考察下一个点,上下左右,如果在障碍物半径内,则继续循环到上述的“如此循环即可,类似于A*算法的膨胀。
2023-11-28 16:59:29
1455
原创 自动驾驶—MPC模型预测控制算法工程实现
Apollo中,LQR和MPC控制器都选用的单车动力学模型作为研究对象,单车动力学模型为非线性系统,但LQR和MPC控制器的目的是为了求最优控制解,在具体的优化求解时,均通过线性化方法将状态方程转化为线性方程进行求解,所以,可以说apollo中LQR和MPC控制器的研究对象均为线性系统。看过Apoll的LQR和MPC源码的朋友会知道,MPC和LQR很类似。MPC的研究对象可以是线性系统,也可以是非线性系统,只不过为了某些需求,如时效性,计算的便捷,操控性等,一般会将非线性系统转换为线性系统进行计算。
2023-11-28 14:31:07
1554
原创 C++boost线程唤醒
消费者则等待数据准备好的通知,收到通知后输出并消费数据。这样可以确保只有一个消费者线程会被唤醒来消费新的数据,从而避免多个线程同时访问和处理同一份数据,确保线程安全。函数用于通知一个等待在条件变量上的线程。它会唤醒一个等待的线程,使其从等待状态返回到可运行状态。这样可以保证消费者线程只有在新的数据产生时才会执行消费操作。在这个示例中,我们创建了一个生产者线程和一个消费者线程。来通知消费者线程有新的数据可供消费。也只会唤醒其中的一个线程,而不是所有线程都唤醒。在本例中,生产者线程在每次生产新数据后会调用。
2023-11-24 11:24:44
527
原创 C++ Boost Thread 编程总结
标准C++线程即将到来。CUJ预言它将衍生自Boost线程库,现在就由Bill带领我们探索一下Boost线程库。就在几年前,用多线程执行程序还是一件非比寻常的事。然而今天互联网应用服务程序普遍使用多线程来提高与多客户链接时的效率;为了达到最大的吞吐量,事务服务器在单独的线程上运行服务程序;GUI应用程序将那些费时,复杂的处理以线程的形式单独运行,以此来保证用户界面能够及时响应用户的操作。这样使用多线程的例子还有很多。但是C++标准并没有涉及到多线程,这让程序员们开始怀疑是否可能写出多线程的C++程序。
2023-11-22 15:24:28
266
原创 机器人算法—ROS TF坐标变换
tf工具包,底层实现采用的是一种树状数据结构,根据时间缓冲并维护多个参考系之间的坐标变换关系,可以帮助程序员在任意时间,将点、向量等数据的坐标,在两个参考系中完成坐标变换。机器人每个关节的传感和运动都是参考自身 以上面的机器人烹饪为例, 头部的视觉传感器(摄像头)参考自己, 计算出煎饼和锅距离自己的距离.相对坐标系就是一个参照物,我们在这个参照物下,来说明自己的位置和姿态。我摆了个什么造型给你看,是横着的,竖着的,躺着的,这个就是姿态。机器人的左手右手的运动又是根据自己的当前位置来控制空间坐标的移动.
2023-11-22 09:42:12
1012
原创 机器人控制—代价地图Costmap的层概述
Costmap2DROS::mapUpdateLoop —— Costmap2DROS::updateMap —— LayeredCostmap::updateMap —— 每一层调用updateBounds —— 每一层调用updateCosts(核心函数)4)小车: std::vector< geometry_msgs::Point> footprint_spec_,这里得到的插件即为各层子地图。1)聚合layer的功能:LayeredCostmap* layered_costmap_
2023-11-21 11:13:14
182
原创 Costmap文献阅读——Layered Costmaps for Context-Sensitive Navigation
许多导航系统,包括无处不在的ROS导航堆栈,在单个成本图上执行路径规划,其中大部分信息存储在单个网格中。这种方法在生成最小长度的无碰撞路径方面非常成功,但是当成本图中的值超出已占用或空闲空间时,它在动态的、充满人员的环境中可能会遇到困难。我们已经创建并实现了一种称为分层成本图的新方法,它通过将成本图数据的处理分离到语义上分离的层来工作。每一层跟踪一种类型的障碍或约束,然后修改用于路径规划的主成本图。
2023-11-14 18:00:37
453
原创 规划文献阅读——Obstacle Avoidance, Path Planning and Control for Autonomous Vehicles
自动驾驶汽车避障需要三个主要层面,即感知、路径规划和制导控制。在本文中,考虑到这三个层次之间的联系,提出了一个全局架构。在环境感知层面,采用基于证据占用网格的方法进行动态障碍物检测。因此,考虑物体的姿态来生成轨迹。后者是基于平滑轨迹的s型函数。最后,控制制导利用该避障轨迹生成合适的转向角。整个策略在我们的实验车上得到了验证。实验结果表明了该方法的有效性。
2023-11-10 16:19:11
156
原创 机器人规划算法——将多边形障碍物离散到地图像素点上?
设多边形的顶点依次为A1,A2…An,要判断的点为P,那么分别计算向量PA1叉乘向量PA2,向量PA2叉乘向量PA3,…,向量PA(n-1)叉乘向量PAn,向量PAn叉乘向量PA1,如果这些叉乘的结果都同向的话,那么这个点就在多边形的内部。判断目标点与多边形的每条边组成的三角形面积和是否等于该多边形,相等则在多边形内部。问题一:如何判断一个点是否在多边形区域内?方法1:向量叉乘判别法。方法2:面积和判别法。
2023-11-10 11:23:58
979
原创 机器人控制算法——局部规划器TEB算法原理及C++可视化仿真
最近一段时间,由于项目需要,一直在做TEB算法的工程化的工作,于是就考虑写下一篇系统些的文章,作为笔记,后续自己看也方便,TEB的英文名Time elastic band”,是一种局部规划器,它的核心思想是将路径规划问题转化为一个带有时间弹性的优化问题,通过对时间弹性的控制,来实现路径的优化。
2023-11-06 09:12:23
2351
原创 机器人控制——C++ HSM状态机基础知识
首先,我们包括hsm/statemachine.h,它引入了整个hsm库。我们宣布一个名为First状态。状态是继承自hsm::State的结构或类。注意:我们更喜欢使用structs而不是类,因为默认情况下它们是公开派生的,所以不需要指定“public”关键字。主要来说,我们初始化一个StateMachine对象,告诉它First是它的初始状态。所有StateMachine都必须有一个初始状态才能启动。
2023-11-06 08:56:28
920
1
原创 机器人控制算法—如何使用C++读取pgm格式的栅格地图并转化为ROS地图格式的data?
近期正在做全局规划+局部动态规划的项目,目前遇到的问题是,我们如何利用C++处理pgm地图文件。即将地图信息要与像素点结合起来。所以我们需要知道地图读取和处理的底层原理,这样更好地在非ROS平台下移植。(1)data[]是按照那张地图图片的自底向上,自左至右逐个像素点存储的.我们举了一个从地图pgm读取到处理成目标地图数据格式data[] 的例子。image_x,image_y表示在图像像素坐标系中的坐标。(2) 在使用二维地图定位导航时,建好的地图文件中包括。基于地图的坐标转换到图像坐标系上。
2023-11-02 09:01:35
1316
1
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人