ROS联合webots实战案例(五)导航功能包入门1

article/2025/5/17 19:31:10

导航功能包入门1

注意:

  • 再学习本系列教程时,应该已经安装过ROS了并且需要有一些ROS的基本知识

为了能和读者进一步讨论问题,建立了一个微信群,方便给大家解答问题,也可以一起讨论问题。
加群链接

webots版本:2020b rev1
ros版本:melodic

在前面几章中分别介绍了在webots中如何创建自己的机器人、添加传感器以及使用手柄或键盘驱动它在仿真环境中移动。在本章中,你会学习到ROS系统最强大的特性之一,它能够让你的机器人自主导航和运动。

1. ROS导航框架

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f9L0hkBb-1610549321728)(1.jpg)]

在图中,能够看到白色、灰色和虚线三种框。白框表示其中的这些功能包集已经在ROS中集成了,并且它们提供的多种节点能够为机器人实现自主导航。

2. 测量或估计机器人姿态

在webots中可以直接使用GPS进行定位。并且利用IMU传感器获取惯性信息来补偿位置和方向值。

姿态(位置+方向):在ROS中,机器人的位置(position:x,y,z)和方向(orientation:x,y,z,w)被定义为姿态。

2.1 在webots中加入GPS和IMU

  1. 打开webots

  2. 在Robot->children下添加如下两个设备
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AlSmLtQ4-1610549321731)(2.jpg)]

  3. 保存并刷新场景

  4. 在控制台下输入以下命令查看是否同步到webots

$ rosservice list

可以看到已经同步上来了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nBhiDwlq-1610549321733)(3.jpg)]

3. 识别障碍物

这里我们使用了激光雷达,在上一节已经带大家配置、调试好了。
在webots中包含了市面上常见的传感器。有距离传感器和视觉传感器等多种传感器。其中距离传感器有基于雷达的距离传感器(常用的是LDS、LRF和LiDAR)、超声波传感器和红外距离传感器等,而视觉传感器包括立体相机、单镜相机、360度相机,以及经常用作深度摄像头的Kinect也都用于识别障碍物。

4. 创建变换

导航包需要知道传感器、轮子和关节的位置。
在这里我们使用tf软件库来完成这部分工作。它会管理坐标变换树。

4.1 创建广播机构

  1. 让我们创建一个代码测试测试一下。在webots_demo/src文件夹下创建一个robot_broadcaster.cpp
  2. 为了不重复造轮子,直接把webots_ros基础代码复制进来。
#include <signal.h>
#include <std_msgs/String.h>
#include "ros/ros.h"#include <webots_ros/set_float.h>
#include <webots_ros/set_int.h>
#include <webots_ros/Int32Stamped.h>using namespace std;
#define TIME_STEP 32    //时钟
#define NMOTORS 2       //电机数量
#define MAX_SPEED 2.0   //电机最大速度ros::NodeHandle *n;static int controllerCount;
static vector<string> controllerList; ros::ServiceClient timeStepClient;          //时钟通讯客户端
webots_ros::set_int timeStepSrv;            //时钟服务数据/*******************************************************
* Function name :controllerNameCallback
* Description   :控制器名回调函数,获取当前ROS存在的机器人控制器
* Parameter     :@name   控制器名
* Return        :无
**********************************************************/
void controllerNameCallback(const std_msgs::String::ConstPtr &name) { controllerCount++; controllerList.push_back(name->data);//将控制器名加入到列表中ROS_INFO("Controller #%d: %s.", controllerCount, controllerList.back().c_str());
}
/*******************************************************
* Function name :quit
* Description   :退出函数
* Parameter     :@sig   信号
* Return        :无
**********************************************************/
void quit(int sig) {ROS_INFO("User stopped the '/robot' node.");timeStepSrv.request.value = 0; timeStepClient.call(timeStepSrv); ros::shutdown();exit(0);
}int main(int argc, char **argv) {setlocale(LC_ALL, ""); // 用于显示中文字符string controllerName;// 在ROS网络中创建一个名为robot_init的节点ros::init(argc, argv, "robot_init", ros::init_options::AnonymousName);n = new ros::NodeHandle;// 截取退出信号signal(SIGINT, quit);// 订阅webots中所有可用的model_nameros::Subscriber nameSub = n->subscribe("model_name", 100, controllerNameCallback);while (controllerCount == 0 || controllerCount < nameSub.getNumPublishers()) {ros::spinOnce();}ros::spinOnce();// 服务订阅time_step和webots保持同步timeStepClient = n->serviceClient<webots_ros::set_int>("robot/robot/time_step");timeStepSrv.request.value = TIME_STEP;// 如果在webots中有多个控制器的话,需要让用户选择一个控制器if (controllerCount == 1)controllerName = controllerList[0];else {int wantedController = 0;cout << "Choose the # of the controller you want to use:\n";cin >> wantedController;if (1 <= wantedController && wantedController <= controllerCount)controllerName = controllerList[wantedController - 1];else {ROS_ERROR("Invalid number for controller choice.");return 1;}}ROS_INFO("Using controller: '%s'", controllerName.c_str());// 退出主题,因为已经不重要了nameSub.shutdown();// main loopwhile (ros::ok()) {if (!timeStepClient.call(timeStepSrv) || !timeStepSrv.response.success) {ROS_ERROR("Failed to call service time_step for next step.");break;}ros::spinOnce();}timeStepSrv.request.value = 0;timeStepClient.call(timeStepSrv);ros::shutdown(); return 0;
}
  1. 在上文中,我们知道我们需要三个检测元件,分别是GPS、IMU、激光雷达
  2. 在进行下面的操作前,我们首先要知道各个元件对应的数据类型是什么。
    使用rosservice list查看服务,找到/robot/gps/enable
    在控制台中输入以下命令对其使能:
$ rosservice call /robot/gps/enable "value: 32"success: True

使能完后使用rostopic list查看gps是否发布了话题/robot/gps/values
在控制台下输入以下命令获取数据类型:

$ rostopic info /robot/gps/values Type: sensor_msgs/NavSatFixPublishers: * /robot (http://mckros-GL553VD:39691/)Subscribers: None

从上面可以看到数据类型为sensor_msgs/NavSatFix,那我们写程序时头文件就要加入#include <sensor_msgs/NavSatFix.h>
介绍了gps数据类型获取的方法,其他两个元件类似。
5. 需要分别对其使能才能在webots中正常运行。

  • 使能GPS并且获取GPS数据

头文件:

#include <sensor_msgs/NavSatFix.h>

订阅gps服务:

    ros::ServiceClient gps_Client;          webots_ros::set_int gps_Srv;            ros::Subscriber gps_sub;gps_Client = n->serviceClient<webots_ros::set_int>("/robot/gps/enable"); // 使能GPS服务gps_Srv.request.value = TIME_STEP;// 判断gps使能服务是否成功if (gps_Client.call(gps_Srv) && gps_Srv.response.success) {ROS_INFO("gps enabled.");// 订阅gps话题,获取数据gps_sub = n->subscribe("/robot/gps/values", 1, gpsCallback);ROS_INFO("Topic for gps initialized.");while (gps_sub.getNumPublishers() == 0) {}ROS_INFO("Topic for gps connected.");} else {if (!gps_Srv.response.success)ROS_ERROR("Failed to enable gps.");return 1;}

gps回调函数:

void gpsCallback(const sensor_msgs::NavSatFix::ConstPtr &values)
{GPSvalues[0] = values->latitude;// 纬度GPSvalues[1] = values->altitude;// 海拔高度GPSvalues[2] = values->longitude;// 经度broadcastTransform(); // tf坐标转换
}
  • 使能IMU并且获取IMU数据

头文件:

#include <sensor_msgs/Imu.h>

订阅IMU服务

    ros::ServiceClient inertial_unit_Client;          webots_ros::set_int inertial_unit_Srv;            ros::Subscriber inertial_unit_sub;inertial_unit_Client = n->serviceClient<webots_ros::set_int>("/robot/inertial_unit/enable"); //订阅IMU使能服务inertial_unit_Srv.request.value = TIME_STEP;// 判断是否使能成功if (inertial_unit_Client.call(inertial_unit_Srv) && inertial_unit_Srv.response.success) {ROS_INFO("inertial_unit enabled.");// 获取话题数据inertial_unit_sub = n->subscribe("/robot/inertial_unit/roll_pitch_yaw", 1, inertial_unitCallback);ROS_INFO("Topic for inertial_unit initialized.");while (inertial_unit_sub.getNumPublishers() == 0) {}ROS_INFO("Topic for inertial_unit connected.");} else {if (!inertial_unit_Srv.response.success)ROS_ERROR("Failed to enable inertial_unit.");return 1;}

回调函数:

void inertial_unitCallback(const sensor_msgs::Imu::ConstPtr &values)
{Inertialvalues[0] = values->orientation.x; Inertialvalues[1] = values->orientation.y;Inertialvalues[2] = values->orientation.z;Inertialvalues[3] = values->orientation.w;broadcastTransform(); // tf坐标转换
}
  • 使能激光雷达
    ros::ServiceClient lidar_Client;          webots_ros::set_int lidar_Srv;            lidar_Client = n->serviceClient<webots_ros::set_int>("/robot/Sick_LMS_291/enable"); // 订阅lidar使能服务lidar_Srv.request.value = TIME_STEP;// 判断是否使能成功if (lidar_Client.call(lidar_Srv) && lidar_Srv.response.success) {ROS_INFO("gps enabled.");} else {if (!lidar_Srv.response.success)ROS_ERROR("Failed to enable lidar.");return 1;}
  • tf 坐标转换:
void broadcastTransform()
{static tf::TransformBroadcaster br;tf::Transform transform;transform.setOrigin(tf::Vector3(-GPSvalues[2],GPSvalues[0],GPSvalues[1]));// 设置原点tf::Quaternion q(Inertialvalues[0],Inertialvalues[1],Inertialvalues[2],Inertialvalues[3]);// 四元数 ->欧拉角q = q.inverse();// 反转四元数transform.setRotation(q); //设置旋转数据br.sendTransform(tf::StampedTransform(transform,ros::Time::now(),"odom","base_link"));// 发送tf坐标关系transform.setIdentity();br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "base_link", "/robot/Sick_LMS_291"));
}

记得将下面这几行加入到CMakelist.txt文件中以正常编译。

# 括号内加入tf
find_package(catkin REQUIRED COMPONENTS )
# 括号内加入tf
catkin_package()add_executable(robot_broadcaster src/robot_broadcaster.cpp)
add_dependencies(robot_broadcaster webots_ros_generate_messages_cpp)
target_link_libraries(robot_broadcaster	${catkin_LIBRARIES})

由于要使用到tf包,所以在package.xml中需要添加如下信息:

<!--导航-->><build_depend>tf</build_depend><build_export_depend>tf</build_export_depend><exec_depend>tf</exec_depend>
  1. 编译
$ cd catkin_ws/
$ catkin_make
  1. 运行试试
$ rosrun webots_demo robot_broadcaster 

运行rqt查看tf tree

$ rosrun rqt_tf_tree rqt_tf_tree

可以看到如下所示图,说明各个节点已经成功连接在一起了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ryVJwnyK-1610549321735)(4.jpg)]

结语

本文也是基于笔者的学习和使用经验总结的,主观性较强,如果有哪些不对的地方或者不明白的地方,欢迎评论区留言交流~

✌Bye


http://chatgpt.dhexx.cn/article/wsjjYYlI.shtml

相关文章

Wav2Vec2 是自动语音识别 (ASR) 的预训练模型

Wav2Vec2 是自动语音识别 (ASR) 的预训练模型&#xff0c;由 Alexei Baevski、Michael Auli 和 Alex Conneau 于 2020 年 9 月 发布。其在最流行的 ASR 英语数据集之一 LibriSpeech 上展示了 Wav2Vec2 的强大性能后不久&#xff0c; Facebook AI 就推出了 Wav2Vec2 的两个多语言…

【webots安装使用教程】

下载webots 最新版 http://www.cyberbotics.com/#download 历史版本 https://github.com/cyberbotics/webots/releases/download/R2020b-rev1/webots-R2020b-rev1-x86-64_ubuntu-16.04.tar.bz2 安装webots 解压缩 tar xjf webots-R2020a-rev2-x86-64.tar.bz2设置WEBOTS_HO…

webots和ros2笔记01-资料

webots版本2020b1ros2版本foxy&#xff0c;案例可以在windows和linux下使用。 roswiki&#xff1a;http://wiki.ros.org/webots_ros2github&#xff1a;https://github.com/cyberbotics/webots_ros2/wiki 版本号对应&#xff08;只列最新两版本&#xff09;&#xff1a; webo…

使用 Transformers 为多语种语音识别任务微调 Whisper 模型

本文提供了一个使用 Hugging Face &#x1f917; Transformers 在任意多语种语音识别 (ASR) 数据集上微调 Whisper 的分步指南。同时&#xff0c;我们还深入解释了 Whisper 模型、Common Voice 数据集以及微调等理论知识&#xff0c;并提供了数据准备和微调的相关代码。如果你想…

使用 Transformers 为多语种语音识别任务微调 Whisper 模型

本文提供了一个使用 Hugging Face &#x1f917; Transformers 在任意多语种语音识别 (ASR) 数据集上微调 Whisper 的分步指南。同时&#xff0c;我们还深入解释了 Whisper 模型、Common Voice 数据集以及微调等理论知识&#xff0c;并提供了数据准备和微调的相关代码。如果你想…

Webots R2022b 发布

这个功能不错webots.cloud 但是&#xff0c;如果网络不畅通&#xff1a; 个把小时也不会有任何进展…… 文档如果网络不畅&#xff0c;也打开困难…… Webots参考手册 R2022b Webots R2022 更改日志 版本 R2022b 于 2022 年 9 月 13 日发布。 新机器人 添加了来自Bitcraze的C…

【webots教程】关于webots的超详细介绍

系列文章 【webots教程】简介与软硬件要求 【webots教程】安装 【webots教程】关于webots的超详细介绍 【webots教程】你在webots搭建的第一个仿真环境 【webots教程】编写你的第一个控制器 【webots教程】简单的避障机器人 Webots是专业的移动机器人仿真软件包。它提供…

Webots与MATLAB联合仿真环境配置

1. 版本 系统&#xff1a;Win10 matlab版本&#xff1a;2023a webots版本&#xff1a;R2020b 2.安装 MATLAB MinGW-w64 C/C Compiler 在使用matlab写控制器之前&#xff0c;需要给matlab安装 MATLAB MinGW-w64 C/C Compiler&#xff0c;因为需要matlab与c进行交互。 下载地址…

ROS联合Webots之麦克纳姆轮篇-搭建麦轮底盘

ROS联合Webots之麦克纳姆轮篇-搭建麦轮底盘 ubuntu版本&#xff1a;20.04 webots版本&#xff1a;2021a ros版本&#xff1a;noetic 0.前言 之前笔者出过ROS联合webots开发教程&#xff0c;在教程中使用的是双轮差动底盘模型&#xff0c;今天笔者将带给笔者麦克纳姆轮的使用…

webots和ros2笔记08-分封

如果阅读完webots_ros2源码&#xff0c;到此已经接近尾声了&#xff0c;为何&#xff1f;已经入门webots和ros2了。 是否需要继续研究就看需求了&#xff01;推荐阅读下文&#xff1a; ROS2机器人操作系统零基础快速入门 https://zhuanlan.zhihu.com/p/96940278 学完ros2基…

VITS 语音合成完全端到端TTS的里程碑

Conditional Variational Autoencoder with Adversarial Learning for End-to-End Text-to-Speech&#xff08;ICML 2021&#xff09; KAKAO公司与KAIST韩国科学院&#xff0c;近年在TTS领域佳作频出&#xff0c;目前最主流的HiFiGAN声码器也是其成果。 目录 概览&#xff1…

webots使用以及第三方模型导入装配、运动学仿真教程

因为项目需要使用机器人的运动学仿真&#xff0c;因此需要的使用相应的机器人运动学仿真软件。在查阅了一些资料以后&#xff0c;决定使用webots作为仿真的基本软件。 但是webots的使用教程&#xff0c;国内基本没有。仅在博客园的内的有一个系列博客&#xff0c;介绍了webots…

ROS联合Webots扩展(二)通过语音控制机器人方案

通过语音控制机器人方案 注意&#xff1a; 再学习本系列教程时&#xff0c;应该已经安装过ROS了并且需要有一些ROS的基本知识此教程以webots_demo为基础 ubuntu版本&#xff1a;20.04 webots版本&#xff1a;2021a ros版本&#xff1a;noetic 0.前言 目前语音机器人已经非常…

Webots和ROS2使用说明(部分翻译)

参考链接 Reference&#xff1a; 文档&#xff1a;http://wiki.ros.org/webots_ros2源码&#xff1a;https://github.com/cyberbotics/webots_ros2 2021更新webotsros2 笔记系列&#xff1a; https://blog.csdn.net/ZhangRelay/article/details/112670542 目前&#xff0c;已…

Webots介绍

Webots介绍 1 介绍1.1 概述1.2 应用1.3 入门要求1.4 技术支持1.5 仿真步骤世界&#xff08;webots定义&#xff09;控制器超级控制器 1.6 平台能力三维建模能力物理引擎外设支持 2 软件使用启动webots用户界面文件菜单编辑菜单查看菜单模拟菜单构建菜单叠加菜单工具菜单帮助菜单…

三维地图Cesium加载天地图

1、首先去天地图官网申请key码&#xff0c;http://lbs.tianditu.gov.cn/server/MapService.html 2、下载Cesium静态资源包文件&#xff0c;如图 3、引入并加载 <div class"background" ><div id"cesiumContainer"></div></div>…

如何使用ArcGIS Pro制作三维地图

概述 随着设备性能提升和程序的升级&#xff0c;三维地图开始逐步登入主流地图&#xff0c;网上有很多使用ArcGIS制作三维地图的教程&#xff0c;这里给大家介绍一下使用ArcGIS Pro制作三维地图的方法&#xff0c;希望能对大家有所帮助。 数据来源 本教程所使用的数据是从水…

03 三维地图添加切片图层

在介绍了创建二维、三维地图之后,我们接下来介绍三维地图如何添加切片图层。地图添加切片图层的最终结果如下图所示,在此过程中默认实现了将业务图层居中显示的效果: 具体操作如下所示: 1 创建HTML基本架构,创建div和引入相关的文件,然后设置div的基本样式,如下: …

三维pcd地图转二维栅格地图

1.概述 在使用导航时&#xff0c;通常会根据二维栅格地图做路径规划&#xff0c;需要将三维点云地图转化成栅格地图。 本文采用滤波及投影的方法&#xff0c; 主要步骤包括 对输入点云进行直通滤波&#xff0c;获取限定高度范围的数据在进行半径滤波&#xff0c;去除部分孤立…

【python数据处理】替代Excel三维地图依据经纬度坐标的绘制热力地图的方式

替代Excel三维地图依据经纬度坐标的绘制热力地图的方式 背景pyecharts绘制 背景 由于某人访问了某地&#xff0c;即便是调整电脑中的区域为别的国家或者地区时候&#xff0c;excel三维地图选择时候依然会弹出很抱歉&#xff0c;三维地图当前不在你的国家/地区使用。这个“当前…