深挖代码 无敌ROS基础

一. 工作空间:

1. 工作空间概念:

其中,build 和devel 内容可以忽略,因为主要面向的是src下用户的源代码。

2. 创建和编译工作空间:

(1)总体流程:

mkdir -p ~/catkin_ws/src  创建工作文件夹【工作空间】
cd ~/catkin_ws/    进入工作文件夹
catkin_make    编译工作空间
source devel/setup.bash    将setup.bash文件source一下
echo source devel/setup.bash >> ~/.bashrc    # 将source后写入.bashrc文件

(2)创建工作空间:

-p 的意思是检测路径是否有这个文件夹,没有则创建。

(3)编译工作空间:

注意要回到工作空间下才能编译。

编译后会多出两个文件夹:devel 和 build。

若有多个功能包,只编译其中一个,则使用下列用法:

(1)编译单独功能包 :
catkin_make -DCATKIN_WHITELIST_PACKAGES="package_name"

单独编译后,如果想将全部功能包编译,则先解除单独编译,上述命令包名为空,即:=“”,就可以全部编译了。

(2)自定义编译线程:加快加载速度

-j 表示 job ,就是任务,可以 j2...

-l 表示load,就是任务数,可以 l4...

catkin_make -j -l

3. 设置环境变量:

告诉系统,这是工作空间的路径。

为何进行source?

关于ros工作空间devel下setup.bash的理解

总体而言就是,使用source命令运行这些脚本文件,则工作空间的环境变量设置可以生效。

对应改进方案,不用每次都进行source:

下面的方法简单理解:写入.bashrc为了每次启动终端都自动启动脚本,识别Ros的环境。

source devel/setup.bash    将setup.bash文件source一下
echo source devel/setup.bash >> ~/.bashrc    # 将source后写入.bashrc文件

二. 功能包:

1. 功能包概念:

2. 功能包内容:

其中:

urdf 是指在rviz里面的三维模型的一个描述文件。

功能包必须有的:CMakeList.txt 和 package.xml,其他非必须。

(1)CMakeList.txt

a. 作用:

定义编译规则

b. 常用 cmakelists 宏:

c. 其他编译宏:

d. 示例:

对应上面的编译宏都有

用对应模块的时候,就去掉注释,文件名改好。

在编译时,对应如下:

(2)package.xml

a. 作用:

功能包的描述信息

b. 必要package.xml标签:

c 可选package.xml标签: 

d. 示例:

对应三个为一组,也可以用一个 depend,来代替上述三个标签。

(3)launch文件:

a. 作用:

实现多节点启动和参数配置的 xml 文件。(这也是 launch 文件存在的意义

b. 标签总览:

c. 跟标签:

d. 嵌套:

等号后面的find 后面是功能包名字,再后面是路径,整体表达就是利用 include 去打开一个 launch 文件。

这个就是打开 xml 文件。

e. 节点<node>:

使用 node 节点可以代替 rosrun

具体操作:

rosrun <package_name> <executable|python>

可以使用以下代替:

<node pkg="package_name" type="executable|python" name="node_name" />

最后这个node_name可以重新定义节点名字

node 常用属性:

示例:

第一行有一个output,对应输出到screen终端

运行一下这个launch文件:

会打印出三个 Info ,对应日志输出。若将output删掉,则没有这三项。

对应 args 是参数输入,如图为base_footprint 。(args与arg不是一个东西)

f. 参数:

注:arg是全局的,args一定要写在 <node> 节点里面,这就是arg与args的区别

g. 参数服务器:

就是一个字典,可以 ”增删查改” 参数。

launch文件将参数加载到参数服务器中。

如图,launch文件打开的是wheeltec_robot这个CPP文件,并且用到 param 将上述五个参数加载到参数服务器当中。

对应的cpp文件中,先初始化ros节点句柄,再调用参数服务器上的参数。

如图,arg 就是将后面的参数赋值给前面的 name 。

发现 param 的name与arg的相同,后面的value赋值的不是一个实参,其意思是加载括号()内的对应 arg 里面的参数。

注:如此麻烦的原因,是arg 可以将全部参数整理到一起,修改很方便;或者一个很常用的Launch,不止在一个地方调用,方便修改。

h. <group>标签:

(1)还是基于上述的launch文件,若在文件中加入group节点:

则对应的 rostopic 和 rosnode 的话题和节点的前面,都会增加 robot1 这个命名空间的别名。

(2)group的 if 用法:

若上述参数相等的话,就运行<group>内的内容。

注:group 标签只能包含 node 标签,不能放在 node 标签下。

i. 重命名:

运行节点的时候,可能会订阅或者发布话题,订阅话题则是输入,发布话题则是输出。

输入的意思是:先重命名,再订阅;

输出的意思是:先重命名,再发布出去。

示例:

(不要忘记斜杠/)

之所以在<node>标签里面加,是因为这些话题是在<node>里面产生的,所以重命名用在外面不会生效。

运行一下Launch文件:看一下话题

之前的话题名字变为了 change 。

3. 创建功能包: 

当然首先都是在 src 目录下

catkin_create_pkg <package_name> [depend1] [depend2] [depend3]

后面的是对应的依赖

示例:

4. 查看功能包:

首先在工作空间下,进入src目录:

cd src

再查看:

ls

三. 话题通信:

1. 话题通信机制:

2. 具体操作:

(1)话题通信三个方面:

发布方

订阅方

配置CMakeList.txt

(2)发布方编写:

核心思想:

    实现流程:
        1.包含头文件 
        2.初始化 ROS 节点:命名(唯一)
        3.实例化 ROS 句柄
        4.实例化 发布者 对象
        5.组织被发布的数据,并编写逻辑发布数据

其中,在初始化的时候,涉及到节点命名。

代码如下:

// 1.包含头文件 
#include "ros/ros.h"
#include "std_msgs/String.h" //普通文本类型的消息
#include <sstream>
int main(int argc, char  *argv[])
{   
    //2.初始化 ROS 节点:命名(唯一)
    // 参数1和参数2 后期为节点传值会使用
    // 参数3 是节点名称,是一个标识符,需要保证运行后,在 ROS 网络拓扑中唯一
    ros::init(argc,argv,"talker");
    
    //3.实例化 ROS 句柄
    ros::NodeHandle nh;//该类封装了 ROS 中的一些常用功能

    //4.实例化 发布者 对象
    //泛型: 发布的消息类型
    //参数1: 要发布到的话题
    //参数2: 队列中最大保存的消息数,超出此阀值时,先进的先销毁(时间早的先销毁)
    ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",10);

    //5.组织被发布的数据,并编写逻辑发布数据
    //数据(动态组织)
    std_msgs::String msg;
    // msg.data = "你好啊!!!";
    std::string msg_front = "Hello 你好!"; //消息前缀
    int count = 0; //消息计数器

    //逻辑(一秒10次)
    ros::Rate r(1);

    //节点不死
    while (ros::ok())
    {
        msg.data = ss.str();
        //发布消息
    }


    return 0;
}     

(3)订阅方编写:

整体思路与发布方相同,但是需要加上回调函数。

回调函数:处理订阅到的话题数据(受外界数据影响的可调用函数 )。

核心思想:

    消息订阅方:
        订阅话题并打印接收到的消息

    实现流程:
        1.包含头文件 
        2.初始化 ROS 节点:命名(唯一)
        3.实例化 ROS 句柄
        4.实例化 订阅者 对象
        5.处理订阅的消息(回调函数)
        6.设置循环调用回调函数

具体代码实现:

// 1.包含头文件 
#include "ros/ros.h"
#include "std_msgs/String.h"

void doMsg(const std_msgs::String::ConstPtr& msg_p){
    ROS_INFO("我听见:%s",msg_p->data.c_str());
    // ROS_INFO("我听见:%s",(*msg_p).data.c_str());
}

int main(int argc, char  *argv[])
{
    setlocale(LC_ALL,"");
    //2.初始化 ROS 节点:命名(唯一)
    ros::init(argc,argv,"listener");
    //3.实例化 ROS 句柄
    ros::NodeHandle nh;

    //4.实例化 订阅者 对象
    ros::Subscriber sub = nh.subscribe<std_msgs::String>("chatter",10,doMsg);
    //5.处理订阅的消息(回调函数)

    //     6.设置循环调用回调函数
    ros::spin();//循环读取接收的数据,并调用回调函数处理

    return 0;
}

(4)CMakeList.txt 配置:

add_executable(Hello_pub
  src/Hello_pub.cpp
)
add_executable(Hello_sub
  src/Hello_sub.cpp
)

target_link_libraries(Hello_pub
  ${catkin_LIBRARIES}
)
target_link_libraries(Hello_sub
  ${catkin_LIBRARIES}
)

(5)执行:

首先启动 roscore,之后启动发布节点和订阅节点,之后运行就好了。

3. topic 命令行指令:

四. 常用指令:

1. 常用指令:

进入目录文件夹:cd xxx
返回上一级目录:cd ..
返回根目录:cd /
查看目录文件夹文件:ls
查看文件夹下文件大小:df -h
以管理员身份复制目录:sudo cp xx / xx
以管理员身份用gedit打开文件:sudo gedit  【gedit是文档编辑器】
 
管理员身份更新包:sudo apt-get update 【常用于换源后的操作】
管理员身份检查更新:sudo apt-get upgrade 【重新检查更新】
 
创建文件:mkdir xx
删除文件:rm xx    【rm -f xx 不询问直接删】
 
查看这个文件的路径名字:pwd
 
【Ros命令】
 
catkin_create_pkg 自定义包名 依赖包 === 创建新的ROS功能包
sudo apt install xxx                === 安装 ROS功能包
sudo apt purge xxx                  ==== 删除某个功能包
rospack list                        === 列出所有功能包
rospack find 包名                   === 查找某个功能包是否存在,如果存在返回安装路径
roscd 包名                          === 进入某个功能包
rosls 包名                          === 列出某个包下的文件
apt search xxx =                    == 搜索某个功能包
rosed 包名 文件名                   === 修改功能包文件
 
搜索功能包:apt seach ros-noetic-* | grep -i gmapping

2. roscore :

(1)是ROS系统的先决条件节点和程序的集合,必须先启动 roscore 才能进行ROS节点通信。(进行通信的前提条件)

(2)roscore启动:ros master, ros 参数服务器,rosout 日志节点 

3.  rosrun 与 roslaunch:

区别在于:rosrun 是运行指定节点,而 roslaunch 是一次性可以多次启动多个节点(因为走Launch 文件)

比如:

rosrun turtlesim turtlesim_node

roslaunch 包名 launch文件名

五. 硬件层:

1. IMU:

IMU传感器是加速度计和陀螺仪传感器的组合,被用来检测加速度和角速度以表示运动和运动强度,就像手机里面的陀螺仪。

ls /dev/tty<tab>    # 查看IMU的串口信息
cd ~/Ros-Autocar    # 进入工作空间
catkin_make         # 编译
 
roslaunch imu_launch imu_msg.launch   # 启动节点
rostopic echo /IMU_data    # 查看IMU的数据话题
rostopic echo /imu_0x91_package    # 查看IMU的另外一个数据话题
 
串口号:ttyUSB0   
tf坐标系名称:base_link
话题名称:IMU_data
 
*使用rviz可视化imu还需要在launch文件夹中加一些东西

注意上述:具体的查看串口信息,启动节点和查看话题的具体操作。

串口:参考ubuntu关于串口的操作

2. 雷达:

以参考的 laser 举例:教程写的非常全面。

雷达配置使用

总体流程为:

(1)创建新的文件夹(比如 ls01b ),并在下面建 src 文件夹。

(2)将雷达压缩包放入 src 文件夹下,并进行解压。

(3)在大文件夹 ls01b 下打开终端,并编译工作空间。

cakin_make

(4)插上雷达,检查雷达串口,看看哪个串口被占用了。(其实就是挨个试)

ls -l /dev/ttyUSB*
//检查单个串口占用,*代表的是端口号

在这里回到前面讲串口的问题,如何判定串口是否被占用呢?

其实很简单,如图所示。

(5)找到对应串口后,赋予该串口权限。

sudo chmod 777 /dev/ttyUSB*
//赋予端口*权限,记得改*!!!

(6)修改 src 目录下面的 launch文件内容中的雷达连接串口,否则启动不了。

(7)运行测试:

先进入工作空间,并进行 source 。之后再运行launch文件,之后打开 rviz 进行扫图。

cd ~/ls01b/
source devel/setup.bash
roslaunch ls01b_v2 ls01b_v2.launch
rosrun rviz rviz

查看话题使用如下:


rostopic echo /scan                    # 查看话题雷达扫描到的各个数据
tf 坐标变换:
<launch>
<node pkg="tf" type="static_transform_publisher" name="link1_broadcaster" args="1 0 0 0 0 0 1 link1_parent link1 100" />
</launch>

对应的 type 是 static_transform_publisher ,这个用于发布两个参考系之间的静态坐标变换,两个参考系一般不发生相对位置变化。

name是自己取的,给这个node取一个名字

args 有两种格式:一种是位移+旋转角,一种是四元数表达

(1)static_transform_publisher x y z yaw pitch roll frame_id child_frame_id period_in_ms
(2)static_transform_publisher x y z qx qy qz qw frame_id child_frame_id period_in_ms
frame_id和 child_frame_id就对应参与变换的两个坐标系
period_in_ms是发布频率,一般默认值为100ms

  • 30
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值