ROS melodic 安装/卸载&常用命令及使用-ubuntu18.04

15 篇文章 1 订阅
4 篇文章 5 订阅

ROS

ROS Answer 官网:https://answers.ros.org/questions/
古月居 · ROS入门21讲:https://www.bilibili.com/video/BV1zt411G7Vn?p=1
古月居 · 对应代码:https://github.com/huchunxu/ros_21_tutorials
中科院软件所-机器人操作系统入门(ROS入门教程)

介绍

ROS是一种机器人开发框架(robot frameworks)
特点:兼容多平台语言共同使用,主要兼容c++和python;结构简单
通信机制采用异步通信:topic话题(pub-sub)机制和C-S(client-Server)机制;
此外:
action基于C-S机制,增加了server端持续反馈,主要用于需长时间响应的情况;
还有tf使用的broadcast,是基于topic,用来发布topic tf信息。

ROS安装

http://wiki.ros.org/melodic/Installation/Ubuntu

ROS软件包下载慢的解决办法

合理选择ROS的镜像源:http://wiki.ros.org/ROS/Installation/UbuntuMirrors
参考链接装ros慢怎么办,只需要少执行一步就可以了
在这里插入图片描述

镜像源配置

#以下命令选其一
##1.国内镜像源,建议
sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.ustc.edu.cn/ros/ubuntu/ $DISTRIB_CODENAME main" > /etc/apt/sources.list.d/ros-latest.list'

#2.官方镜像源,非常慢
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
#以下命令选其一
#1.
sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116
#2.
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654

安装包

sudo apt update
#ros全安装,包括rviz还有2D/3D仿真包
sudo apt install ros-melodic-desktop-full
#安装一些常用依赖包:
sudo apt install python-rosdep python-rosinstall python-rosinstall-generator python-wstool build-essential
#安装ros管理依赖工具
sudo apt install python-rosdep
sudo rosdep init
rosdep update

rosdep Init ERROR解决

cannot download default sources list from:【closed】
解决:报raw.githubusercontent.com/xxx 网站down的

  1. ping raw.githubusercontent.com看看网站是否通
  2. sudo vim /etc/hosts
    加入以下内容:

151.101.84.133 raw.githubusercontent.com

或者

151.101.76.133 raw.githubusercontent.com

或者去http://tool.chinaz.com/dns找到 raw.githubusercontent.com对应的ip,TTL值大一些的。

  1. sudo service networking restart重启network服务
  2. ping raw.githubusercontent.com看看网站是否通了,对应ip是否为151.101.84.133。

rosdep update一直timeout

解决rosdep update一直timeout的问题

sudo vim /usr/lib/python2.7/dist-packages/rosdep2/gbpdistro_support.py

DOWNLOAD_TIMEOUT = 15.0改大一点。

配置环境变量

#设置打开终端生效
echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc
source ~/.bashrc

创建ros工作空间:

mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
catkin_init_workspace

ros 下source会清理ROS_PACKAGE_PATH,因此一个终端启动跨工作空间下的包会有问题
通过以下的方式将空间变量添加到ROS_PACKAGE_PATH变量可解决此问题
export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:/xxx/ws/src/packxxx

ROS测试

#启动ros server
roscore
#启动小海龟节点node
rosrun turtlesim turtlesim_node
#启动小海龟键盘控制节点node
rosrun turtlesim turtle_teleop_key

在这里插入图片描述

ROS使用

ros master server启动

roscore

多机ros协同

从机配置:
export ROS_MASTER_URI=http://[master_ip]:11311
eg: export ROS_MASTER_URI=http://192.168.1.2:11311
主机配置:启动roscore [ros master]的机器,如果ROS_HOSTNAME用的host_name,须在/etc/hosts中对应匹配上master_ip.
export ROS_HOSTNAME=[host_name/master_ip]
export ROS_MASTER_URI=http://[host_name/master_ip]:11311
这样即可以在从机的export下的终端接收到主机的topic。

远程rviz

  1. 可以使用远程桌面方式,参考https://blog.csdn.net/weixin_41469272/article/details/105747164
  2. 使用ssh -X 远程打开桌面服务,需要桌面环境
    ssh [user_name]@[user_ip] -X
    rviz可以远程打开rviz

package 包管理

#软件包列表
rospack list
#查找软件包目录
rospack find package-name
#查看指定包下文件目录
rosls package-name
#直接进入对应包路径下
roscd package-name
#编辑ros文件,有时候需要编辑apt安装的ros包的文件,以下就会启用vi编辑pacname/filename文件
rosed pacname filename
#新建包
catkin_create_pkg <package_name> [depend1] [depend2] [depend3]
#查看包依赖
rospack depends <package_name>

#自定义包卸载就用rm 删除其对应的src下的文件夹。
#系统自带包,则通过安装包管理工具apt一类的进行卸载。

#手动创建包
1.mkdir tstpck 或者 cp xxtstpck tstpck
2.cd tstpck
3.vi package.xml
#填入对应的<package><name><depend>等信息。一般填入<package><name>信息包就能被识别了
#使用rosls 及 roscd查看是否系统是否找的道tstpak了
#记得要source对应ws的devel/setup.sh

Metapackage

Metapackage(功能包集)是把一些相近的功能模块、 软件包放到一起。
metapacakge和普通package不同点是:
CMakeLists.txt :加入了catkin_metapackage()宏, 指定本软件包为一个metapacakge。
package.xml :标签将所有软件包列为依赖项, 标签中添加标签声明。
以上参考https://www.cnblogs.com/long5683/p/9941458.html

node 节点管理

#启动节点
rosrun package-name executable-name 
#查看节点列表
rosnode list
#查看节点信息
rosnode info node-name
#停止节点
rosnode kill node-name
#为启动的节点命名node_name
rosrun pkg_name node_type __name:=node_name
#查看是否能联通node
rostopic ping node_name
#启动节点时映射topic,类似节点输入
rosrun node_name node_name origin_topic:=new_topic
 <node pkg="pkg_name" type="exe_name" name="node_name1" args="arg1 arg2 arg3" respawn="true" output="screen">  

1.pkg:功能包名称
2.type:可执行文件,节点名称
3.name:定义节点运行的名称,将覆盖节点中init()赋予节点的名称。
4.output = “screen”
将节点的标准输出打印到终端屏幕,默认输出为日志文档。
5.respawn=”true”
复位属性,该节点停止时,会自动重启,默认为false。
6.respawn_delay =“30” (可选,默认为0)ROS indigo中的新功能
如果respawn为true,请在尝试重新启动之前检测到节点故障后等待respawn_delay秒。
6.required=”true”
必要节点,当该节点终止时,launch文件中的其他节点也被终止。
7.launch-prefix =“prefix arguments” (可选)
用于预先添加到节点的启动参数的命令/参数。这是一个强大的功能,使您能够启用gdb,valgrind,xterm,漂亮或其他方便的工具。
eg: launch-prefix = “command-prefix”
roslaunch 命令 的一个潜在的缺点:相比我们原来对每个节点在单独的终端使用 rosrun 命令启动的做法,roslaunch 则是让所有的节点共享同一个终端。 那些只需要生产简单的日志消息文件而不需要终端(console)输入的节点是容易管理的,而那些依赖终端输入的节点,它可能要优先的保留在独立的终端上。
在launch文件中,使用launch-prefix=”xterm -e”.属性,可以使启动这个 node 元素的 rosrun 命令大致相当于:xterm -e rosrun pkg_name node_name.
xterm 命令会开一个新的终端窗口。 -e 参数告诉 xterm :执行其命令行剩余部分(rosrun turtlesim turtle_teleop_key)。=
用于预先添加到节点的启动参数的命令/参数。这是一个强大的功能,使您能够启用gdb,valgrind,xterm,漂亮或其他方便的工具。
8.args =“arg1 arg2 arg3” (可选)
传递参数到节点。
9.machine =“machine-name” (可选)
在指定机器上启动节点。
10.ns =“foo” (可选)
在“foo”命名空间中启动节点。
11.clear_params =“true | false” (可选)
在启动前删除节点的私有命名空间中的所有参数。
12.output =“log | screen” (可选)
如果’screen’,stdout / stderr从节点将被发送到屏幕。如果是“log”,stdout / stderr输出将被发送到$ ROS_HOME/ log中的日志文件,stderr将继续发送到屏幕。默认值为“log”。
13.cwd =“ROS_HOME | node” (可选)
如果为“node”,则节点的工作目录将设置为与节点的可执行文件相同的目录。在C Turtle中,默认值为“ROS_HOME”。在Box Turtle(ROS 1.0.x)中,默认值是’ros-root’。使用’ros-root’在C Turtle中已被弃用。
参考链接-https://www.cnblogs.com/qixianyu/p/6579798.html

launch文件

launch文件用来同时启动多个node节点及配置更多的参数。在roslaunch时,ros master会被启动
在launch文件头使用<?xml version="1.0"?>声明,在vi中打开该launch,可以使用xml格式显示(带颜色区分)。
respawn复位节点
respawn=”true”,这样当节点停止的时候,roslaunch会重新启动该节点。

 <node name="Stereo" pkg="ORB_SLAM2" type="Stereo" 
	args=" $(find ORB_SLAM2)../../../Vocabulary/ORBvoc.txt $(find ORB_SLAM2)Asus_imsee.yaml false" 
	output="screen" respawn="true" respawn_delay="10">
 </node>
launch文件中对sub/pub topic remap

来自launch文件remap标签

<!--start_talker.launch-->
<launch>    
    <node pkg="test" type="talker" name="talker" output="screen">
    <!--talker节点发布的topic为/talker-->
        <!--一个例子:将talker节点发布的话题/talker映射到/re_talker的名字上去-->
        <remap from="/talker" to="/re_talker" />        
    </node> 
</launch>

通过rosrun也可以进行topic remap

launch中启动新的终端
#1
    <!-- 使用launch-prefix="gnome-terminal --" -->
    <node pkg="prometheus_mission" type="planning_mission" name="planning_mission" output="screen" launch-prefix="gnome-terminal --">
        <param name="planning_mission/control_yaw_flag" value="false" type="bool"/>
    </node>
#2
#xterm 命令会开一个新的终端窗口。 -e 参数告诉 xterm :执行其命令行剩余部分(rosrun package_name node_name)。
    <!-- 使用launch-prefix="xterm -e" -->
    <node pkg="prometheus_mission" type="planning_mission" name="planning_mission" output="screen" launch-prefix="xterm -e">
        <param name="planning_mission/control_yaw_flag" value="false" type="bool"/>
    </node>
<!--start_test1.launch-->
<launch>    
    <node pkg="test" type="test1" name="test1" output="screen">
    <!--test1节点需要订阅话题为/talker_mid-->
        <!--一个例子将节点订阅的topic改名字为/re_talker-->
        <remap from="/talker_mid" to="/re_talker" />
    </node>
</launch>

使用roslauch传递参数:在xxx.launch中写入参数

示例:
节点公有参数

<launch>
  #所有节点的公共参数
  <param name="use_sim_time" value="true"/>
  #launch文件的外部参数
  <arg name="scan_topic" default="sick_scan" />
  #node本身也可通过arg传递节点外部参数
  <node pkg="gmapping" type="slam_gmapping" name="slam_gmapping" args="" output="screen">
  #单个节点的私有参数
    <param name="throttle_scans" value="1"/> 
  ...
  </node>
... ...
<\launch>

eg: vins_estimator/launch:

<launch>
    <arg name="config_path" default = "$(find feature_tracker)/../config/inde/inde_config.yaml" />
          <arg name="vins_path" default = "$(find feature_tracker)/../config/../" />
... ...
    <node name="vins_estimator" pkg="vins_estimator" type="vins_estimator" output="screen">
       <param name="config_file" type="string" value="$(arg config_path)" />
       <param name="vins_folder" type="string" value="$(arg vins_path)" />
    </node>
... ...
    </node>
</launch>

eg: loam_velodyne

  <group if="$(arg rviz)">
    <node launch-prefix="nice" pkg="rviz" type="rviz" name="rviz" args="-d $(find loam_velodyne)/rviz_cfg/loam_velodyne.rviz" />
  </group>

在节点源程序中,对launch文件中的公有参数读取

ros::init(argc, argv, "xxxx");
ros::NodeHandle nh;
//3中获取函数
//1
nh.param<std::string>("data_save_dir", data_save_dir, "~/");//可以设置默认值
//2
nh->getParam("/aruco_mapping/marker_size", temp_marker_size);
//3
ROS::param::get()

节点私有参数
节点私有参数读取:将"~"赋值给node,便可读取xxx.launch 文件中定义的param。

ros::NodeHandle private_nh_("~");
if(!private_nh_.getParam("throttle_scans", throttle_scans_))
        throttle_scans_ = 1
ros::NodeHandle nh()句柄设置

ros::NodeHandle nh; 不设置句柄时,ROS节点与整个lauch的命名空间一致(launch 文件中 ns=="namespace")。

设置句柄:
ros::NodeHandle nh("node_namespace");
该节点命名空间变为:namespace/node_namespace
ros::NodeHandle pn1("~"); 该节点命名空间与其节点名对应,与
ros::init(argc, argv, "node_name");结合使用,此时该节点命名空间变为:namespace/node_name

来自https://blog.csdn.net/weixin_44346182/article/details/122389695

args传入多个参数

<launch>
    <node name="map_server" pkg="map_server" type="map_server" args="$(find costmap_2d)/test/willow-full-0.025.pgm 0.025" />
    <node name="rosplay" pkg="rosbag" type="play"
        args="-s 5 -r 1 --clock --hz=10 $(find costmap_2d)/test/simple_driving_test_indexed.bag" />
</launch>

launch中添加其他launch文件:使用$(find 节点名称)

<launch>
 <include file="$(find imsee_ros_wrapper)/launch/start.launch" />
 <node name="rviz" pkg="rviz" type="rviz" args="-d $(find imsee_ros_wrapper)/rviz/imsee.rviz" 
output="screen" />
</launch> 

group使用
launch group用来管理node的启动。

  1. 通过group 赋予node的命名空间,防止不同节点间运行时,参数冲突。
<group ns="turtlesim1">
      <node pkg="turtlesim" name="sim" type="turtlesim_node"/>
        </group>
<group ns="turtlesim2">
      <node pkg="turtlesim" name="sim" type="turtlesim_node"/>
        </group>
  1. 通过group if/unless 管理节点的条件性启动。
<group if="0-or-1" />
	<node pkg="turtlesim" name="sim" type="turtlesim_node"/>
. . .
</group>
<group unless="1-or-0" />
	<node pkg="turtlesim" name="sim" type="turtlesim_node"/>
. . .
</group>

launch load yaml file

https://www.jianshu.com/p/13efab3f67e0
https://www.cnblogs.com/zx-hit/p/11777992.html

topic 消息管理

#列出所有topic清单
rostop list
#实时指定topic内容 -n 指定打印的topic数
rostopic echo -n 1 [topic]
#rostopic取消打印矩阵或者字符串
rostopic echo --nostr [topic]
rostopic echo --noarr [topic]

#rostopic 
#发布topic,-r 指定发布次数
rostopic pub [-1] <topic> <msg_type> [-r 1] -- [args] [args]
#查看topic发布的频率
rostopic hz [topic]
#改变topic发布频率:intopic为要改变的topic名称,outtopic为更改后发布topic名称(可省),msgs_per_sec要设置的频率
#temp:rosrun topic_tools throttle messages <intopic> <msgs_per_sec> [outtopic]
rosrun topic_tools throttle messages /topic 1.0
#重映射消息名称:
rosrun <rostype> <rosnode> <topic_origin_name>:=<topic_new_name>
eg:
rosrun rospy_tutorials talker chatter:=/wg/chatter

service 服务管理

#列出service 清单
rosservice list
#service调用
rosservice call [service] [args]

bag使用

#记录所有信息
rosbag record -a -O filename.bag
#记录过滤掉/monitor/*之外的其他topic
rosbag record -a -O xxx.bag -x "/monitor/(.*)"
#记录指定topic信息
rosbag record -O subset <topic1> <topic2>
#查看rosbag内容
rosbag info <bagfile_name>

#指定播放的起始时间戳
#rosbag play <your bagfile name> -s <start time>
#等待一定时间之后发布bag文件中的内容
rosbag play <your bagfile name> -d <delay time>
#回放指定话题
rosbag play <your bagfile name> --topics <topics>

#过滤包
#创建一个除了/tf消息的新包
rosbag filter file.bag <no_tf_name>.bag "topic != '/tf'"
rosbag filter input.bag output.bag "topic == '/velodyne_point_cloud' or topic =='/visensor/imu' or topic == '/visensor/left/image_raw'"
#根据时间过滤
rosbag filter input.bag output.bag "t.to_sec() <= xxxx"
#同时过滤topic和时间
rosbag filter input.bag output.bag "topic == '/topic' and t.to_sec() <= xxxx"



#重映射topic信息(将output.bag中topic1转为topic2)
rosbag play <output.bag>  /topic1:=/topic2
#回放bag内容 -r可以制定回放topic的速率倍数,-r 0.5是指播放速率为原先速率的一半
rosbag play (-r 2) <bagfile_name>

#bag.active恢复
1. rosbag reindex xxx.bag.active
2. rosbag fix xxx.bag.active result.bag
#bag包裁剪
rosbag filter input.bag output.bag "t.to_sec() >= [start time] and t.to_sec() <= [end time]"
#[start time]和[end time]如Bag Time: 1623406311

rosbag --clock与use_sim_time离线调试

#发布clock虚拟时钟
1. rosbag play xxx.bag --clock
#打开/use_sim_tim参数,使参数设置后启动的node均使用虚拟时钟
2. rosparam set /use_sim_time true

eg:

3. rosbag play xxx.bag --clock
4. rosparam set /use_sim_time true
5. rosrun tf static_transform_publisher 0 0 0 0 0 0  camera_init map 50
#便可成功订阅camera_init frame下的点云或pose等,解决message removedbecause it is too old问题

rqt_bag查看bag数据

查看bag包指定帧数据
rqt_bag bag_name.bag

//同步订阅两个topic然后处理
        message_filters::Subscriber<sensor_msgs::PointCloud2> cloud_sub(n, VELODYNE_TOPIC, 1);
        message_filters::Subscriber<lidar_camera_calibration::marker_6dof> rt_sub(n, "lidar_camera_calibration_rt", 1);

        typedef sync_policies::ApproximateTime<sensor_msgs::PointCloud2, lidar_camera_calibration::marker_6dof> MySyncPolicy;
        Synchronizer<MySyncPolicy> sync(MySyncPolicy(10), cloud_sub, rt_sub);
        sync.registerCallback(boost::bind(&callback_noCam, _1, _2));

void callback_noCam(const sensor_msgs::PointCloud2ConstPtr& msg_pc,
                    const lidar_camera_calibration::marker_6dof::ConstPtr& msg_rt)

message管理

#列出所有消息名称
rosmsg list
#查看topic下指定message的信息
rosmsg show [msg_type]

parameter 参数管理

#参数设置
rosparam set [parame_name] [args] 
#参数获取查看
rosparam get [parame_name]
#加载指定文件中的所有参数配置
rosparam load [file_name] [namespace]
#参数删除
rosparam delete
节点参数传递

使用rosrun时传递参数:

  1. rosrun package node _parameter:=value 注意parameter前加下划线。
    示例:
    rosrun gmapping slam_gmapping _map_update_interval:=1.0
  2. 使用argv传递main函数参数:
    示例:
    rosrun map_server map_saver -f ~/Documents/test

也可使用launch文件传入参数

tf 查看

  • ROS tf定义的坐标系是右手法则,Z轴朝上,X轴到Y轴为逆时针方向
    在这里插入图片描述

http://wiki.ros.org/tf/

#查看两个坐标系之间的变换,以下为查看map和odom之间的变换关系
rosrun tf tf_echo map odom
#查看tf tree
rosrun rqt_tf_tree rqt_tf_tree
#报告在ROS上任意两个坐标系发布的变换。
rosrun tf tf_echo [reference_frame] [target_frame]
#使用命令发布tf变换信息
#1使用yaw pitch roll欧拉角来定义旋转
#period_in_ms每秒发布多少次(速率) 100为不错的选择
rosrun tf 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
#examples tf pub use cmd
rosrun tf static_transform_publisher 0 0 0 0 0 0 base_link velodyne 100

log级别查看与设置

有三种方法设置日志级别:

  • 第一个是通过配置文件设置所有节点的日志级别
    在launch 文件里指定一个config 文件, 在这个 config 文件里制定哪些pkg 输出什么级别的log.
    步骤:
  1. 把下面的文本copy 到 某个folder 下的 某个文本文件里,然后重命名为 rosconsole.config
# Set the default ros output to warning and higher
log4j.logger.ros=WARN
# Override my package to output everything
log4j.logger.ros.move_base=DEBUG
  1. 修改你使用的launch 文件,假设是fake_amcl.launch, 在这个launch 文件里添加下面的文本。
  <env name="ROSCONSOLE_CONFIG_FILE"
       value="myfolder_path/rosconsole.config"/>   // myfolder_path  是你的rosconsole.config 文件所在的文件夹
  • 第二个是在运行时,通过rqt_logger_level(以前叫rxloggerlevel)或rqt_console (以前叫rxconsole) 工具来设置日志级别
#打开图形界面,选择对应的
rqt_logger_level

在这里插入图片描述

  • 第三个通过 rosconsole API来设置:
#include <ros/console.h>
if( ros::console::set_logger_level(ROSCONSOLE_DEFAULT_NAME, ros::console::levels::Debug) ) {
   ros::console::notifyLoggerLevelsChanged();
}

ros log级别设置 https://www.jianshu.com/p/8d23b4c12f6f

  • launch文件中设置log级别
1.ROS2
<node pkg="rosservice" type="rosservice" name="set_move_base_log_level" args="--log-level debug" />
2.
<node pkg="rosservice" type="rosservice" name="set_move_base_log_level" args="call --wait /move_base/set_logger_level 'ros.move_base' 'debug'" />

命令

  1. ROS2: rosrun packname nodename __log_level:=debug
  2. rosservice call /node-name/set_logger_level rospackage-name Debug

log显示出处

launch文件中加入:

<env name="ROSCONSOLE_FORMAT"      value="${logger}: { ${message} }" />

也同直接设置环境变量:
export ROSCONSOLE_FORMAT='${logger}: ${message}'
log打印结果如下:
设置前:
在这里插入图片描述
设置后:
在这里插入图片描述

显示数据曲线rqt_plot

rqt_plot打开绘图界面,输入’/'下方会提示选项,输入变量全路径,点击右侧+号,下方会显示变量跟随时间的变化情况
在这里插入图片描述

nodelet 使用

nodelet是实现将多个算法运行在同一个进程。
ROS中的 nodelet
http://wiki.ros.org/nodelet
node与nodelet实现通信的不同:node每个节点各占一个进程,需通过topic互相通信。nodelet各算法节点占用一个线程,所有算法共享一个进程,通信也通过topic,但是nodelet的topic通信底层是通过指针的传递实现的。

在这里插入图片描述
node:图中说node间的topic交互是通过tcp(连接式)通信方式;
nodelet:各个节点虽与node相似,也采用topic方式。但是其nodelet的各个节点运行在一个进程中,实际topic的交互是通过指针传递实现。详细使用见参考链接。
因此使用nodelet启动的node的起始不是main,而是onInit()

map_server地图管理

sudo apt install ros-melodic-map-server
保存地图:
rosrun map_server map_saver map:=/<Map Topic> -f PATH_TO_YOUR_FILE/mymap
显示地图:运行map_server 重新发布topic节点,在使用rviz add topic显示地图。
rosrun map_server map_server mymap.yaml

rivz

rviz终端输入rviz可直接启动rviz;
点击rviz下方add可以添加要显示的topic
rviz -d xxx.rviz可以根据xxx.rviz的配置订阅topic信息进行显示。

pcl &点云pcd保存及显示

保存并查看Loam的三维点云地图-https://blog.csdn.net/qq_36396941/article/details/83048415
PCL点云库-https://blog.csdn.net/qq_43145072/article/details/85953948

#pcl库文件安装
sudo apt-get install libpcl-dev
#pcl工具安装,如pcl_viewer
sudo apt-get install  pcl-tools
#从bag中保存点云地图,input.bag为bag包,/laser_cloud_surround为点云topic
rosrun pcl_ros bag_to_pcd input.bag /laser_cloud_surround pcd
#查看pcd点云图
pcl_viewer map.pcd 

c++中保存点云地图

#include <iostream>  
#include <pcl/io/pcd_io.h>  
#include <pcl/point_types.h>  
#include <pcl/point_cloud.h>  
  
using namespace std;  // 可以加入 std 的命名空间  
  
int  
main(int argc, char** argv)  
{  
pcl::PointCloud<pcl::PointXYZ>::Ptr INcloud(new pcl::PointCloud<pcl::PointXYZ>);    // 存放提取出来的边界点云  
if (pcl::io::loadPCDFile<pcl::PointXYZ>("boudary_200_100.pcd", *INcloud) == -1)//*打开点云文件。  
{                                                                           //带路径的格式【注意路径的反斜杠与电脑自己的不同】:if (pcl::io::loadPCDFile<pcl::PointXYZ>("E:/rabbit_gra.pcd", *cloud) == -1)  
PCL_ERROR("Couldn't read that boundary pcd file\n");                             // //不带路径的格式【只是把路径删掉即可】:if (pcl::io::loadPCDFile<pcl::PointXYZ>("rabbit_gra.pcd", *cloud) == -1)  
return(-1);  
}  
//写入磁盘  
//写入方法一:  
pcl::PCDWriter writer;  
writer.write<pcl::PointXYZ>("name_cluster.pcd", *INcloud, false);//将点云保存到PCD文件中  
  
//写入方法二:  
pcl::io::savePCDFileASCII("name_cluster.pcd", *INcloud); //将点云保存到PCD文件中  
} 

两种读取和写入pcd点云文件的方法
ros pcl sensor::pointcloud2 转换成pcl::pointcloud

rosclean log清除

rosclean check 查看ros log文件及大小
rosclean purge 清除log文件

编译

  1. 使用catkin_make
cd ~/catkin_ws
#编译所有文件,catkin_make需再catkin workspace下进行,而 catkin_init_workspace是在src下
catkin_make
#编译指定包
catkin_make -DCATKIN_WHITELIST_PACKAGES="package1;package2"
#指定不编译指定包
catkin_make -DCATKIN_BLACKLIST_PACKAGES="package1;package2"
#或:
catkin_make --pkg package_name
#或:
catkin_make --source [package_path] --build build/[pacakge_name]
#或:直接使用cmake/make
#build和devel可以放在ws下,也可以指定放在package下,这样可以通过ROS_PACKAGE_PATH来切换同名包
#ROS会在ws以及package path下去寻找可用的可执行文件
cd [packge_path]
mkdir build
cmake ..
make
export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:${PWD}

2.使用catkin build
安装:sudo apt install python-catkin-tools
使用:catkin build [pacname]
3. 使用rosmake

#安装包依赖,根据package.xml配置
rosdep install pkg_name
#进入package目录
roscd pkg_name
#编译该package
rosmake pkg_name

catkin_package
catkin_package DEPENDS 和 CATKIN_DEPENDS 用来告诉 catkin 需要将你程序包的哪些依赖项传递给使用 find_package(…) 查找你的程序包的程序包。
catkin_package()是catkin提供的CMake宏,用于为catkin提供构建、生成pkg-config和CMake文件所需要的信息。

使用rosws管理工作空间

sudo apt-get install python-rosinstall
mkdir ~/rosbuild_ws
cd ~/rosbuild_ws
rosws init . /opt/ros/indigo
mkdir package_dir
rosws set ~/rosbuild_ws/package_dir -t .
echo "source ~/rosbuild_ws/setup.bash" >> ~/.bashrc
cd package_dir
<copy package to .>
rosmake package_name

参考链接:https://docs.ros.org/en/independent/api/rosinstall/html/rosws_tutorial.html

可执行文件位置

ros 自定义workspace编译的可执行文件位置/${workspace}/devel/lib/
ros安装的包的可执行文件位置:/opt/ros/melodic/lib

卸载

#卸载ros相关包
sudo apt-get purge ros-*
#卸载相关自动下载的依赖包
sudo apt-get autoremove

ros接口定义查询

ros接口定义查询http://docs.ros.org/jade/api/

roscpp

launch文件中arg与param的区别:
arg是launch文件的参数,在roslaunch xxxpackage xxx.launch argname:=argvalue
param是启动的node要传入的参数

 // 使用“~”则private_nh 可以接受launch文件中给定的param
ros::NodeHandle private_nh("~");
private_nh.param("base_global_planner", global_planner, std::string("navfn/NavfnROS"));

ros::spin 和ros::spinOnce – ROS消息回调处理函数:
ros::spin 和ros::spinOnce 都是用来触发ros节点订阅的所有topic的消息处理函数。
两者区别在于ros::spinOnce只触发一次消息处理,而ros::spin会block触发所有节点订阅的topic处理函数。
对于有些传输特别快的消息,需要注意合理控制消息池大小和ros::spinOnce()执行频率; 比如消息送达频率为10Hz, ros::spinOnce()的调用频率为5Hz,那么消息池的大小就一定要大于2,才能保证数据不丢失,无延迟。
ros::spin()和ros::spinOnce()的意义与区别-https://blog.csdn.net/datase/article/details/79742421

ROS Time

http://wiki.ros.org/Clock
http://wiki.ros.org/roscpp/Overview/Time
ROS 中有 ROS::Time()和ROS::WallTime()
参考:https://blog.csdn.net/sru_alo/article/details/102893536

  • ROS Time可以被人为修改,你可以暂停它,可以加速,可以减速;
  • Wall Time不可以被修改,Wall Time可以理解为墙上时间,墙上挂着的时间没有人改变的了,永远在往前走;

在开启一个Node之前,当把use_sim_time设置为true时,这个节点会从clock Topic获得时间。所以操作这个clock的发布者,可以实现一个让Node中得到ROS Time暂停、加速、减速的效果。同时下面这些方面都是跟Node透明的,所以非常适合离线的调试方式。当把ROSbag记下来以后重新play出来时,加两个横杠,–clock,它就会发布出这个消息。

如,使用rosbag播放数据包时,处理的数据的程序也想采用bag中的时间,就可以将use_sim_time设为true,同时播放bag包时加上–clock。但是同时rosbag play时 可以加上-r [r]来改变ros的播放速度。因此模拟时间可通过ROS::Time()获得,且此时的时钟时间是可调,可控的。为防止特殊情况下,用户需要使用绝对的系统时间,则ROS::WallTime()。

当不开启use_sim_time时,ROS::Time()和ROS::WallTime()获取的时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。

两外:ROS::Time也分time 和 duration 两种类型,相应的有 ros::Time 和 ros::Duration 类。
time 表示的是时刻
duration 表示的是时间间隔

ROS程序调试

参考链接

  1. 直接使用gdb gdb -ex run --args ./exefile
    eg: gdb -ex run --args ./Examples/Monocular/mono_euroc Vocabulary/ORBvoc.txt Examples/Monocular/EuRoC.yaml ../EUROC_dataset/mav0/cam0/data Examples/Monocular/EuRoC_TimeStamps/MH05.txt
gdb --args /exefile arg1 args2

在ros程序运行出错时会红色字打印cmd,将cmd后的命令直接跟在gdb --args之后就可以进行调试

2.在launch文件中加入:
python : launch-prefix="xterm -e python -m pdb "
c++: launch-prefix="xterm -e gdb -ex run --args "

eg:

<node pkg="waypoint_follower" type="pure_persuit" name="pure_pursuit" output="screen" launch-prefix="xterm -e gdb -ex run --args">
        <param name="is_linear_interpolation" value="$(arg is_linear_interpolation)"/>
</node>

然后使用rosrun或launch运行node,程序会自动启用gdb

附:gdb常用命令:
r: 运行程序
c:继续运行程序
s:单步运行程序
bt:打印backtrace调用栈区符号表

https://www.linuxidc.com/linux/2016-03/129600.htm

  • 7
    点赞
  • 105
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值