大一上学期生涯总结
半年过去了,我也成功度过了我的大一上学期。在这里,让我稍微概括一下我在我的大一上学期都做了什么。
ROS是一个集成了许多工具和库的机器人操作框架,以节点之间的通信实现对数据的处理和硬件的操控。
Windows上有用choco分发的ROS2,不过目前功能不算完善,所以关于ROS的开发工作一般在Linux系列系统上进行,这里我们选用20.04的Ubuntu来配置工作环境。
参考AutoLabor上的教程,配置主要有以下步骤。
1 | sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.tuna.tsinghua.edu.cn/ros/ubuntu/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list' |
1 | sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 |
1 | sudo apt update |
1 | echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc |
.bashrc
是Ubuntu系统根目录下的记录环境变量的文件,以后我们自己编译了什么项目也可以把路径放在这里。1 | sudo apt install python3-rosdep python3-rosinstall python3-rosinstall-generator python3-wstool build-essential |
1 | sudo rosdep init |
在ROS里实现HelloWorld,首先需要我们构造一个节点,然后让该节点在日志中将HelloWorld作为信息输出。
要搭建工作环境,首先需要在工作区执行
1 | catkin_make |
这个命令的执行需要文件夹下存在src
目录,该目录存放我们的工程文件。
之后要编译其中的工作文件我们也需要执行同样的命令。
完成命令后,会额外生成./bin
与./devel
文件夹,与./src/CMakeLists.txt
./bin
中会存放生成的构建文件./devel
中会存放生成的执行脚本与一些头文件
要开始编写节点,我们需要先创建工具包,进入./src
目录,并执行
1 | catkin_create_pkg 包名 roscpp rospy std_msgs |
包名
的命名不要携带任何大写字母、下划线与连接线,用纯小写字母,这是一种命名规范roscpp
或者rospy
是C++语言或Python语言的基础工具包,std_msgs
是标准消息库,之后的通信会用到。
将add_executable()
和target_link_libraries()
取消注释,表明本次构建生成可执行文件。
编写项目的流程就我目前总结如下:
packages.xml
,添加所需依赖CMakeLists.txt
,设置编译过程msg
和srv
这种依赖,那么先编译一遍为了实现HelloWorld,我们需要编写如下代码
1 | #include "ros/ros.h" |
尤其值得注意的是,#include "ros/ros.h"
这一行,为了让VSCode找到ros的头文件,我们要编辑includePath
设置,一般来说在ros的默认安装路径下头文件在/opt/ros/noetic/include/**
(最后那个**指包含所有子目录)
进行ros编程,最重要的就是节点,我们首先初始化并声明自己这个节点,然后再下一步输出日志。
int argc, char *argv[]
是运行该节点时的一些基本参数,argc
代表参数数量,argv
是参数列表
没有额外参数传入时,argv[0]
为文件路径,argv[1]
为节点名称,argv[2]
为日志路径,argc
为3
。
有额外参数时,argv[1]
是第一个额外参数,argv[2]
等等以此类推,argc
为参数数量加上3
。
首先启动ROS内核
1 | roscore |
然后在工作区内启动节点
1 | source ./devel/setup.bash |
ROSMaster负责储存一系列参数,发布者修改其中的参数,订阅者可以获取其中的参数。
工程文件详见param
文件夹,以下提出几个要点:
setParam()
设置并准备发布参数,hasParam()
检测参数存在性,getParam()
以获取参数值。ROSMaster负责让发布者与订阅者建立连接,发布者接受来自订阅者的数据请求,并相应回给订阅者处理后的信息。
工程文件详见srv
文件夹,以下提出几个要点:
srv
文件夹并准备.srv
描述文件.srv
文件中---
上方的是订阅者请求信息,下方是发布者回应信息CMakeLists.txt
中,应当将add_service_files()
与generate_messages()
方法打开,并添加message_generation
作为第三方库到find_package()
中。package.xml
中,应当添加如下引用 1 | <build_depend>message_generation</build_depend> |
rosrun
指令后添加参数,参数会被argv
储存waitForService()
方法可以在节点没启动时阻塞进程ROSMaster负责让发布者与订阅者建立连接,发布者发布消息,订阅者接收信息。
工程文件详见msg
文件夹,其使用了.msg
文件自定义传输数据,以下提出几个要点:
msg
文件夹并准备.msg
描述文件.msg
文件中一行一个变量定义CMakeLists.txt
中,应当将add_message_files()
与generate_messages()
方法打开,并添加message_generation
作为第三方库到find_package()
中。package.xml
中,应当添加如下引用 1 | <build_depend>message_generation</build_depend> |
1 | rqt_graph |
这个命令可以查看所有的节点状态与它们之间的关系。
创建工具包时使用catkin_create_pkg
命令需在./src
资源文件夹内进行。
编写msg
文件或者srv
文件时,int
类型定义为int32
,long long
为int64
,double
为float64
,记得查表。
计算行列式的值是线性代数中非常重要的一个知识点,由于个人能力限制,我一直都没有完成这道题目。好在有一位已经自学了线性代数的同学帮忙,我完成了这道题目。本篇文章不只会展示题解,也会同时解释清楚行列式的值的计算方法,并介绍行列式的部分实际应用。
对于一个数列{a1, a2, a3 ... an}
来说,其中的子数对(ai, aj)
若其满足i < j
且ai > aj
,则称其为一个逆序对,一个数列的逆序对数为其包含逆序对的总数,记作t(a1, a2 ... an)
。
举个例子,对于{4, 8, 2, 10, 7}
来说,其满足条件的逆序对为(4, 2)
,(8, 2)
,(8, 7)
,(10, 7)
,故其逆序对数为4
。
计算一组随机数据的逆序对数最快的算法是仿照归并排序的分治法,复杂度为O(NlogN)
。