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

亚博microros小车-原生ubuntu支持系列:20 ROS Robot APP建图

依赖工程

新建工程laserscan_to_point_publisher

src/laserscan_to_point_publisher/laserscan_to_point_publisher/目录下新建文件laserscan_to_point_publish.py

#!/usr/bin/env python3import rclpy
from rclpy.node import Node
from geometry_msgs.msg import PoseStamped, TransformStamped
from nav_msgs.msg import Path
from sensor_msgs.msg import LaserScan
import tf2_ros
import mathclass laserscanToPointPublish(Node):def __init__(self):super().__init__('robot_pose_publisher')self.subscription = self.create_subscription(LaserScan,'/scan',self.laserscan_callback,10)self.sacn_point_publisher = self.create_publisher(Path,'/scan_points',10)def laserscan_callback(self, msg):
#            print(msg)angle_min  = msg.angle_minangle_increment = msg.angle_incrementlaserscan = msg.ranges# 获取激光雷达数据
#            print(laserscan)laser_points = self.laserscan_to_points(laserscan, angle_increment, angle_increment) self.sacn_point_publisher.publish(laser_points)def laserscan_to_points(self, laserscan, angle_min, angle_increment):points = []angle = angle_minlaser_points = Path()for distance in laserscan:x = distance * math.cos(angle + 135)#获取当前激光雷达数据点的的坐标值y = distance * math.sin(angle + 135)pose = PoseStamped()pose.pose.position.x = xpose.pose.position.y = ypoints.append(pose)angle += angle_incrementlaser_points.poses = pointsreturn laser_pointsdef main(args=None):rclpy.init(args=args)robot_laser_scan_publisher = laserscanToPointPublish()rclpy.spin(robot_laser_scan_publisher)robot_pose_publisher.destroy_node()rclpy.shutdown()if __name__ == '__main__':main()

robot_pose_publisher_ros2

src/robot_pose_publisher_ros2/src/目录下新建robot_pose_publisher.cpp

/*!* \file robot_pose_publisher.cpp* \brief Publishes the robot's position in a geometry_msgs/Pose message.** Publishes the robot's position in a geometry_msgs/Pose message based on the TF* difference between /map and /base_link.** \author Milan - milan.madathiparambil@gmail.com* \date April 20 1020*/#include <chrono>
#include <memory>#include "rclcpp/rclcpp.hpp"
#include "geometry_msgs/msg/pose_stamped.hpp"
#include "geometry_msgs/msg/pose.hpp"
#include "geometry_msgs/msg/transform_stamped.hpp"
#include "tf2_ros/transform_listener.h"
#include "tf2_ros/buffer.h"using namespace std::chrono_literals;/* This example creates a subclass of Node and uses std::bind() to register a* member function as a callback from the timer. */class RobotPosePublisher : public rclcpp::Node
{
public:RobotPosePublisher() : Node("robot_pose_publisher"){tf_buffer_ = std::make_shared<tf2_ros::Buffer>(this->get_clock());tf_listener_ = std::make_shared<tf2_ros::TransformListener>(*tf_buffer_);this->declare_parameter<std::string>("map_frame","map");this->declare_parameter<std::string>("base_frame","base_link");this->declare_parameter<bool>("is_stamped",false);this->get_parameter("map_frame", map_frame);this->get_parameter("base_frame", base_frame);this->get_parameter("is_stamped", is_stamped);if (is_stamped)publisher_stamp = this->create_publisher<geometry_msgs::msg::PoseStamped>("robot_pose", 1);elsepublisher_ = this->create_publisher<geometry_msgs::msg::Pose>("robot_pose", 1);timer_ = this->create_wall_timer(50ms, std::bind(&RobotPosePublisher::timer_callback, this));}private:void timer_callback(){geometry_msgs::msg::TransformStamped transformStamped;try{transformStamped = tf_buffer_->lookupTransform(map_frame, base_frame,this->now());}catch (tf2::TransformException &ex){return;}geometry_msgs::msg::PoseStamped pose_stamped;pose_stamped.header.frame_id = map_frame;pose_stamped.header.stamp = this->now();pose_stamped.pose.orientation.x = transformStamped.transform.rotation.x;pose_stamped.pose.orientation.y = transformStamped.transform.rotation.y;pose_stamped.pose.orientation.z = transformStamped.transform.rotation.z;pose_stamped.pose.orientation.w = transformStamped.transform.rotation.w;pose_stamped.pose.position.x = transformStamped.transform.translation.x;pose_stamped.pose.position.y = transformStamped.transform.translation.y;pose_stamped.pose.position.z = transformStamped.transform.translation.z;if (is_stamped)publisher_stamp->publish(pose_stamped);elsepublisher_->publish(pose_stamped.pose);}rclcpp::TimerBase::SharedPtr timer_;rclcpp::Publisher<geometry_msgs::msg::PoseStamped>::SharedPtr publisher_stamp;rclcpp::Publisher<geometry_msgs::msg::Pose>::SharedPtr publisher_;size_t count_;bool is_stamped = false;std::string base_frame = "base_link";std::string map_frame = "map";std::shared_ptr<tf2_ros::TransformListener> tf_listener_;std::shared_ptr<tf2_ros::Buffer> tf_buffer_;
};int main(int argc, char *argv[])
{rclcpp::init(argc, argv);rclcpp::spin(std::make_shared<RobotPosePublisher>());rclcpp::shutdown();return 0;
}

其中获取结果 buffer_.lookup_transform  获取map到base_link的坐标变化, 再发布robot_pose。

rosbridge_server

这个没有安装也需要安装下。

启动脚本

src/yahboomcar_nav/launch/map_cartographer_app_launch.xml

<launch><include file="$(find-pkg-share rosbridge_server)/launch/rosbridge_websocket_launch.xml"/><node name="laserscan_to_point_publisher" pkg="laserscan_to_point_publisher" exec="laserscan_to_point_publisher"/><include file="$(find-pkg-share yahboomcar_nav)/launch/map_cartographer_launch.py"/><include file="$(find-pkg-share robot_pose_publisher_ros2)/launch/robot_pose_publisher_launch.py"/><include file="$(find-pkg-share yahboom_app_save_map)/yahboom_app_save_map.launch.py"/>
</launch>

 这里运行了以下几个launch文件和节点Node:

  • rosbridge_websocket_launch.xml:开启rosbridge服务相关节点,启动后,可以通过网络连接到ROS

  • laserscan_to_point_publisher:把雷达的点云转换发布到APP上进行可视化

  • map_cartographer_launch.py:cartographer建图程序

  • robot_pose_publisher_launch.py:小车位姿发布程序,小车位姿在APP进行可视化

  • yahboom_app_save_map.launch.py:保存地图的程序

程序功能说明

小车连接上代理,运行程序,打开手机上下载的【ROS Robot】app,输入小车的IP地址,选择ROS2,点击连接,即可连接上小车。通过滑动界面的轮盘可以控制小车,缓慢控制小车走完建图的区域,最后点击保存地图,小车会保存当前建好的地图。

启动

#小车代理
sudo docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:humble udp4 --port 8090 -v4
#摄像头代理(先启动代理再打开小车开关)
docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:humble udp4 --port 9999 -v4

首先启动小车处理底层数据程序,终端输入,

ros2 launch yahboomcar_bringup yahboomcar_bringup_launch.py

启动APP建图命令,终端输入,

ros2 launch yahboomcar_nav map_cartographer_app_launch.xml
#启动ESP32 摄像头
ros2 run yahboom_esp32_camera sub_img

手机APP显示如下图,输入小车的IP地址,【zh】表示中文,【en】表示英文;选择ROS2,下边的Video Tpoic选择/usb_cam/image_raw/compressed,最后点击【连接】

image-20231219143224710

这个ip就是小车的配置ip。成功连接上后,跑一点地图显示如下,

 

有个问题就是app上不显示摄像头画面。我看亚博官网的文章上也没有显示,不知道为啥,猜测是控制小车的ip跟摄像头代理的不是1个。

另外的感受这个比较难操控小车,速度太快了,不如键盘好掌握。

以上。

相关文章:

亚博microros小车-原生ubuntu支持系列:20 ROS Robot APP建图

依赖工程 新建工程laserscan_to_point_publisher src/laserscan_to_point_publisher/laserscan_to_point_publisher/目录下新建文件laserscan_to_point_publish.py #!/usr/bin/env python3import rclpy from rclpy.node import Node from geometry_msgs.msg import PoseStam…...

Dockerfile构建容器镜像

Dockerfile 是一种文本格式的配置文件&#xff0c;用于自动化构建 Docker 镜像。它包含了一系列指令&#xff08;命令&#xff09;&#xff0c;每个指令定义了容器镜像构建过程中的一步操作。通过Dockerfile&#xff0c;我们可以指定基础镜像、安装依赖、配置环境变量、复制文件…...

python 在包含类似字符\x16、\x12、\x某某的数组中将以\x开头的字符找出来的方法

话不多说直接看例子&#xff1a; import re# 原始列表 data [\x16, \x17, s, \x16, hello, \x1A]# 正则表达式匹配以 \x 开头的字符串 pattern r^\\x# 找出以 \x 开头的字符 result [item for item in data if isinstance(item, str) and re.match(pattern, repr(item)[1:-…...

Spring Bean 的生命周期介绍

Spring Bean 的生命周期涉及多个阶段&#xff0c;从实例化到销毁&#xff0c;在开发中我们可以通过各种接口和注解介入这些阶段来定制化自己的功能。以下是详细的生命周期流程&#xff1a; 1. Bean 的实例化&#xff08;Instantiation&#xff09; 方式&#xff1a;通过构造函…...

调用腾讯云批量文本翻译API翻译srt字幕

上一篇文章介绍了调用百度翻译API翻译日文srt字幕的方法。百度翻译API是get方式调用&#xff0c;参数都放在ur中&#xff0c;每次调用翻译文本长度除了接口限制外&#xff0c;还有url长度限制&#xff0c;而日文字符通过ur转码后会占9个字符长度&#xff0c;其实从这个角度来讲…...

车载软件架构 --- 软件定义汽车面向服务架构的应用迁移

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 简单&#xff0c;单纯&#xff0c;喜欢独处&#xff0c;独来独往&#xff0c;不易合同频过着接地气的生活…...

Baklib引领内容中台与人工智能技术的创新融合之路

内容概要 在数字化转型的浪潮中&#xff0c;各行业正在面临前所未有的挑战与机遇。内容中台作为一种新的概念&#xff0c;逐渐进入了企业的视野&#xff0c;它不仅是一个技术平台&#xff0c;更是提供了整合和管理内容的新思路。从根本上&#xff0c;内容中台旨在提升企业对信…...

想品客老师的第十一天:模块化开发

模块化概念 模块化开发可以提高代码的可维护性、可读性和复用性&#xff0c;同时降低开发和调试的复杂性&#xff0c;把业务根据功能分开写&#xff0c;解决变量命名的冲突&#xff0c;可以开放部分接口给类&#xff08;例如调用模块里的一个函数&#xff09;也更适合团队协作…...

接入DeepSeek大模型

接入DeepSeek 下载并安装Ollamachatbox 软件配置大模型 下载并安装Ollama 下载并安装Ollama&#xff0c; 使用参数ollama -v查看是否安装成功。 输入命令ollama list&#xff0c; 可以看到已经存在4个目录了。 输入命令ollama pull deepseek-r1:1.5b&#xff0c; 下载deepse…...

基于遗传算法的256QAM星座图的最优概率整形matlab仿真,对比优化前后整形星座图和误码率

目录 1.算法仿真效果 2.算法涉及理论知识概要 3.MATLAB核心程序 4.完整算法代码文件获得 1.算法仿真效果 matlab2022a仿真结果如下&#xff08;完整代码运行后无水印&#xff09;&#xff1a; GA优化曲线&#xff1a; 优化前后星座图对比 优化前后误码率对比 仿真操作步骤…...

JavaScript系列(57)--工程化实践详解

JavaScript工程化实践详解 &#x1f3d7;️ 今天&#xff0c;让我们深入探讨JavaScript的工程化实践。良好的工程化实践对于构建可维护、高质量的JavaScript项目至关重要。 工程化基础概念 &#x1f31f; &#x1f4a1; 小知识&#xff1a;JavaScript工程化是指在JavaScript开…...

Linux-CentOS的yum源

1、什么是yum yum是CentOS的软件仓库管理工具。 2、yum的仓库 2.1、yum的远程仓库源 2.1.1、国内仓库 国内较知名的网络源(aliyun源&#xff0c;163源&#xff0c;sohu源&#xff0c;知名大学开源镜像等) 阿里源:https://opsx.alibaba.com/mirror 网易源:http://mirrors.1…...

【大数据技术】案例03:用户行为日志分析(python+hadoop+mapreduce+yarn+hive)

用户行为日志分析(python+hadoop+mapreduce+yarn+hive) 搭建完全分布式高可用大数据集群(VMware+CentOS+FinalShell) 搭建完全分布式高可用大数据集群(Hadoop+MapReduce+Yarn) 本机PyCharm远程连接虚拟机Python 搭建完全分布式高可用大数据集群(MySQL+Hive)...

LeetCode 0680.验证回文串 II:两侧向中间,不同就试删

【LetMeFly】680.验证回文串 II&#xff1a;两侧向中间&#xff0c;不同就试删 力扣题目链接&#xff1a;https://leetcode.cn/problems/valid-palindrome-ii/ 给你一个字符串 s&#xff0c;最多 可以从中删除一个字符。 请你判断 s 是否能成为回文字符串&#xff1a;如果能…...

第二十章 存储函数

目录 一、概述 二、语法 三、示例 一、概述 前面章节中&#xff0c;我们详细讲解了MySQL中的存储过程&#xff0c;掌握了存储过程之后&#xff0c;学习存储函数则肥仓简单&#xff0c;存储函数其实是一种特殊的存储过程&#xff0c;也就是有返回值的存储过程。存储函数的参数…...

架构规划之任务边界划分过程中承接分配

架构师在边界划分的过程中需要做什么事情呢&#xff1f;接下来&#xff0c;我们会讨论一些关于任务分配的 基础假设&#xff0c;以及由这些基础假设而带来的决策路径。 所谓任务边界划分&#xff0c;就是判定某个任务在多个承接方中&#xff0c;应该归属到哪个承接方的过程。…...

【C++】线程池实现

目录 一、线程池简介线程池的核心组件实现步骤 二、C11实现线程池源码 三、线程池源码解析1. 成员变量2. 构造函数2.1 线程初始化2.2 工作线程逻辑 3. 任务提交(enqueue方法)3.1 方法签名3.2 任务封装3.3 任务入队 4. 析构函数4.1 停机控制 5. 关键技术点解析5.1 完美转发实现5…...

vsnprintf的概念和使用案例

vsnprintf 是 C/C 标准库中用于格式化字符串的安全函数&#xff0c;属于 <stdio.h>&#xff08;C&#xff09;或 <cstdio>&#xff08;C&#xff09;头文件。它是 snprintf 的可变参数版本&#xff08;v 表示 va_list&#xff09;&#xff0c;允许通过 va_list 处理…...

解读隐私保护工具 Fluidkey:如何畅游链上世界而不暴露地址?

作者&#xff1a;Techub 独家解读 撰文&#xff1a;Tia&#xff0c;Techub News 隐私不只是个人权利的象征&#xff0c;更是我们迈向透明、信任未来的重要过渡桥梁。如果你还未意识到隐私的重要性&#xff0c;推荐阅读 KeyMapDAO 的文章《「被出卖的自由」&#xff1a;我到底该…...

Linux环境Kanass安装配置简明教程

Kanass是一款国产开源免费的项目管理软件&#xff0c;本文将介绍如何快速在linux centos环境下安装配置&#xff0c;以快速上手。 1. 安装 以下以linux centos7下安装为例。 下载&#xff0c;下载地址:Kanass - 下载&#xff0c;下载Linux安装包如tiklab-kanass-1.0.4.rpm&am…...

4. 打破ASR技术瓶颈:Whisper-1模型原理、性能与落地实践

1. 引言 语音识别&#xff08;Automatic Speech Recognition, ASR&#xff09;是人工智能领域的核心技术方向之一&#xff0c;其历史可追溯至20世纪50年代贝尔实验室的Audrey系统——这一仅能识别10个英文数字的早期系统&#xff0c;标志着机器理解人类语音的开端。此后半个多…...

【C++ 多态】虚函数 · 虚表 · 重写,一篇彻底弄明白!

C 多态详解 C多态是面向对象的核心灵魂&#xff0c;本文将由浅入深&#xff0c;带你循序渐进地掌握多态的方方面面&#xff0c;全程干货&#xff0c;坐稳发车~ ദ്ദി˶&#xff70;̀֊&#xff70;́ )✧ 文章目录C 多态详解1. 什么是多态&#xff1f;2. 运行时多态的实现前…...

如何在手机上免费播放任何视频格式?VLC for Android给你答案!

如何在手机上免费播放任何视频格式&#xff1f;VLC for Android给你答案&#xff01; 【免费下载链接】vlc-android VLC for Android, Android TV and ChromeOS 项目地址: https://gitcode.com/gh_mirrors/vl/vlc-android 你是否曾经遇到过这样的情况&#xff1a;下载了…...

解锁PS4游戏存档的终极掌控:Apollo Save Tool深度技术解析

解锁PS4游戏存档的终极掌控&#xff1a;Apollo Save Tool深度技术解析 【免费下载链接】apollo-ps4 Apollo Save Tool (PS4) 项目地址: https://gitcode.com/gh_mirrors/ap/apollo-ps4 在PlayStation 4的游戏生态中&#xff0c;PS4存档管理和游戏数据修改一直是玩家和开…...

Midjourney Basic计划真实体验:7天高强度测试+37组对比图,揭示隐藏限制与生产力断层

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Midjourney Basic计划真实体验&#xff1a;7天高强度测试37组对比图&#xff0c;揭示隐藏限制与生产力断层 过去一周&#xff0c;我以全职创作者身份深度使用 Midjourney Basic 计划&#xff08;$10/月…...

IntelliNode:统一AI模型调用,加速Node.js智能应用开发

1. 项目概述&#xff1a;从IntelliNode到智能应用开发的新范式最近在开源社区里&#xff0c;一个名为“IntelliNode”的项目引起了我的注意&#xff0c;更具体地说&#xff0c;是它的核心库intelligentnode/Intelli。乍一看这个名字&#xff0c;你可能会联想到“智能节点”&…...

芯片巨头并购软件公司:从硬件竞赛到软硬协同的产业变革

1. 行业现象背后的深层逻辑最近和几个在芯片设计公司和EDA软件公司工作的老朋友聊天&#xff0c;大家不约而同地提到了一个趋势&#xff1a;芯片巨头们的手&#xff0c;伸得越来越长了。以前是买IP核、买制造厂&#xff0c;现在则是频频出手&#xff0c;将一家家软件公司收入囊…...

高校食堂学生信息录入系统开发实战|从0到1搭建简易Web系统

大家好&#xff5e; 最近完成了一个适合高校课程作业、小型食堂管理使用的「大学食堂学生信息录入系统」&#xff0c;全程用纯前端技术实现&#xff0c;无需复杂后端环境&#xff0c;双击即可运行&#xff0c;今天就来分享一下开发全过程、功能细节和使用技巧&#xff0c;适合刚…...

LocalClaw:一键部署本地AI工作站,简化macOS大模型环境搭建

1. 项目概述&#xff1a;LocalClaw macOS 安装器 如果你是一名在 Apple Silicon Mac 上折腾本地大语言模型的开发者或爱好者&#xff0c;那么对 LM Studio 和 OpenClaw 这两个名字一定不陌生。前者是一个强大的本地 LLM 运行和管理工具&#xff0c;后者则是一个开源的、类 Chat…...

AI工作流引擎:基于DAG与智能体的自动化任务编排实践

1. 项目概述&#xff1a;当AI遇上工作流&#xff0c;一场效率革命的开端 最近在GitHub上看到一个挺有意思的项目&#xff0c;叫 DahnM20/ai-flow 。光看名字&#xff0c;你可能会觉得这又是一个“AI自动化”的玩具&#xff0c;但仔细研究其源码和设计理念后&#xff0c;我发现…...