简介:不对具体功能系统讲解,网上已经很多了,只记录关键点和踩坑点。
不对具体功能系统讲解,网上已经很多了,只记录关键点
https://robot-ros.com/robot
感觉很有用,至少这个tf很有用,讲的很清楚,比好多收费卖课的大忽悠要强(cvlife)
https://robot-ros.com/robot/33772.html
tf主页
tf教程主页
void SigintHandler(int sig)
{
std::cout << “ros is is shutting down.” << std::endl;
ros::shutdown();
}
signal(SIGINT, SigintHandler);
while(ros::ok()){
//do
}
这样能用ctrl+c中断循环,ros::shutdown()和ros::ok()联动
官方IO demo
rosbag record -o $save_dir/navi_loc \
/map \
/scan1 \
/scan2 \
/odom \
/tf \
/odom_wheel \
/IMU_data \
/landmark \
/relative_detection/relativepose \
/localization_manager/status \
/cart_comm_node/twist_cmd \
--lz4 --split --duration=30m
30分一个包,不停录制
rosbag play navi_loc_2022-03-17-10-33-05_0.bag navi_loc_2022-03-17-10-33-15_1.bag navi_loc_2022-03-17-10-33-25_2.bag navi_loc_2022-03-17-10-33-35_3.bag
catkin_make --pkg
log 或 screen
If ‘screen’, stdout/stderr from the node will be sent to the screen. If ‘log’, the stdout/stderr output will be sent to a log file in $ROS_HOME/log, and stderr will continue to be sent to screen. The default is ‘log’.
cwd=“ROS_HOME|node”(optional)
经验证的创建ws和编译的博客
(可能是特例)
工作自定义msg会安装到/opt/raccoon下,因为版本变动,需要修改一个msg(如果msg不同,C++读取msg会成为NULL,只要差一个字段就不行)。结果手动改了半天/opt/raccoon/share下的*.msg没有任何效果,dpkg”重装“msg就有效果。发现正经生效的msg应该是/opt/raccoon/include下的**.h,改完编译即可生效?还没。。。最好重新”安装“一次。
重装msg就成功了(具体的*.deb脚本那里还没研究太多)
为什么呢?因为消息*.h头文件里还有md5校验值,纯手动改字段是不行的。
而为什么python又无所谓,字段变不变都能读取消息呢?可能没有校验过程,不如C++ 严格,也取决于官方接口的实现。
绑定回调带参数(留_1,后边是参数)
ros::Subscriber sub2=ros_node_handler.subscribe (
"/cartographer_ros/initialpose",100000, boost::bind(&LocPoseCallback, _1, &curr_bag_name,&bag,&new_arrival_time));
绑定类成员(参数可走类成员)
ros::Subscriber initialpose_sub = ros_node_handler.subscribe("/cartographer_ros/initialpose", 10000000, &LocalizationEvo::InitialPoseCallback, this);
void LocalizationEvo::InitialPoseCallback(const geometry_msgs::PoseStamped::ConstPtr& msg)
{
ros::Time t = ros::Time(msg->header.stamp.sec,msg->header.stamp.nsec);
bag_->write("localization_pose_saved", t,msg);
}
根据rviz,ROS Elapsed比WalLElapsed要少,simulation的time比真实时间要慢
rosbag play --clock的解释
spinonce和具体的参数设置有关,使用虚拟时间则必须按clock走,设置为false则能自然触发不阻塞。
rosparam set use_sim_time false
如果设置true,ros::time有独立的时间,设置false,ros::time::now()则是系统时间?和WallTime一样。
rviz同样也会受此参数干扰,但是需要启动之前设置(可能),并且有可能有一些“bug”,经常需要重启一下roscore才能看到一些变化,这也是比较容易产生困惑的点,很多实验不生效,则需要多重启roscore。
同样的计算过程,产出的pose被记录下来得到不同的长度,单独用rosbag record去记录,发现实际“丢”很多,用rostopic hz去看,50hz,但是不行rate随便设了30,加上缓冲区长度只有1,所以丢了。
106719/177200=0.6
30hz/50hz=0.6
一个灵活的睡眠方案:设定10hz,100ms的间隔,但是不是睡眠100ms,你计算20ms,它睡眠80ms,你计算50ms,它睡眠50ms,是一种目标导向的接口,目标是处理频率。
问题:rate的sleep很依赖clock,如果use_sim_time,播放包的时候也是靠clock这个topic去给系统同步时间的,1.时间是否有延迟?(不影响频率,但是时间戳会有不一致,验证,打印某一pose时间和time)2.是否能保证足够精细?(通过经验看,carto用,可能范围足够,只是探究原理)
很多莫名其妙的停止与暂停都可能是缺乏clock造成的,尤其使用虚拟时间为true,并且播包结束。
keep-alive命令,播放所有内容后不结束,继续发布/clock并且时间累加。
rosbag play -k --clock test.bag
rostopic echo /clock
接收测试,验证clock存活并累加。
排除了名称不对,手动pub等,确定是消息发布不出去~!
但是在一个典型的while循环重复发消息的demo中就可以(但我的需求是一次)。同样的ros::ok()判断,while循环和if一次性就是不一样,后者会发不出任何消息(不是程序关闭,哪怕发布消息之后再sleep暂停也不行),必须在发布前sleep(至少3秒),消息可发出
ros::Publisher pub = nh.advertise("/gridMap", 1);
if(ros::ok()){//单次发送
sleep(3.5);//起作用,加入此句后可以发出消息
pub.publish(map);
sleep(3.5);//不起作用
}
原因:ROS MASTER负责协调各node,node之间需要建立点对点连接,事实上时间时给advertise<>()的,是它需要一个时延才能真正生效。
参数限制的问题直接导致无法将回调写成类成员。无法与外部交互。
低级方法:全局变量,复制消息。
正确方法:
一个用[boost绑定]
ros::Subscriber sub2=ros_node_handler.subscribe (
"/cartographer_ros/initialpose",1, boost::bind(&LocPoseCallback, _1, &curr_bag_name,&bag,&new_arrival_time));
void LocPoseCallback(const geometry_msgs::PoseStamped::ConstPtr& msg, std::string* curr_bag_name,rosbag::Bag* bag,ros::WallTime* new_arrival_time) {}
一个是直接往参数列表加,但是有规则。
没事不要乱用rosrun?
实际工程,复杂的多版本管理环境,git或许能应付,但是ros不能。
在a分支注册了一份package_mine,在b分支也注册一份,哪怕#source devel是b分支,但是rosrun仍然可能跑的是a分支。
用roslaunch。
但是可能同样不能避免,source错devel的悲剧。尤其脚本复杂,变量增加,批量操作以后。
所以存疑!!!!
裸ros不够,需要安装一些库
官网安装
PS:我的工作环境还有几个包,解压3rd_deps.tar.gz安装
cd ceres-solver
mkdir build
cd build
cmake .. -DCXX11=ON
make
sudo make install
cd protobuf
mkdir build
cd build
cmake -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release -Dprotobuf_BUILD_TESTS=OFF ../cmake
../cmake
make
sudo make install
abseil
cd abseil-cpp
mkdir build
cd build
cmake \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
-DCMAKE_INSTALL_PREFIX=/usr/local/stow/absl \
..
make
sudo make install
官网的一些依赖包,包含lua5.2等,可参考,但是我的工作环境不需要完全照抄。
需要 liblua5.2-dev
一些传感器数据相关的,打印太多会导致程序跑不动,使用LOG_EVERY_N会好一些,但是有个问题,如果是跟踪数据流,可能打印出来的时间不太一致,需要注意.
cartographer中
T GetYaw(const Eigen::Quaternion& rotation)
rotation乘以单位矩阵?
arctan(y,x)
issues
https://github.com/cartographer-project/cartographer_ros/issues/460
ros rviz中各种数据类型介绍
line_strip与line_list的区别:
0-1,1-2,2-3…
0-1,2-3,4-5…
已经修复了,但是你没更新到那个版本还是要注意
https://github.com/ros-visualization/rviz/pull/1662
-11 is SIGSEGV, and -6 is SIGABRT.
/usr/include/bits/signum.h路径下找不到这个头文件,
或者使用
find /usr -name signum.h
ubuntu16.04是在
/usr/include/x86_64-linux-gnu/bits/signum.h
不同系统不同路径,用IDE引用一下头文件#include
#define SIGABRT 6 /* Abort (ANSI). */
#define SIGIOT 6 /* IOT trap (4.2 BSD). */
可以把非格式化的log信息转存成为bag,然后按时序播放,在rviz显示
header.frame_id=“map”
没有frame_id不能显示在rviz
只需要在cmakelist的目标中追加一个gfags即可
target_link_libraries(pose_listener ${catkin_LIBRARIES} gflags)
解决CMAKE找不到的问题&VSCODE无法调试的问题:
前提:已安装
sudo ln -s /usr/include/eigen3/Eigen /usr/include/Eigen
关于使用过程中偶然发现的一个“bug”。
DEFINE_bool(var1,false,“this is a boolean”) ;
#a.exe --var1 false
#a.exe --var1 0
无论怎么设置,FLAGS_var1都是1
后来发现是传参方法“不得当”。
我意为是–var1 空格 false
其实应该是
#a.exe --var1=false
甚至是
#a.exe --novar1
(只限于bool)
但是坑就坑在,大多数情况下,你用空格传参也都没问题,所以问题发的就比较隐蔽。
BTW:
DECLARE_bool(var1); 用于在其他文件共享使用变量
下面方法可以顺便看输入参数是什么(bool不能传更广泛的值是个遗憾,但是至少确定是ParseCommandLineFlags(从设置的默认false)修改bool值为1的)
static bool ValidateBool(const char* flagname, bool value) {
if (value ==0) // value is ok
return true;
printf("Invalid value for --%s: %d\n", flagname, (int)value);
return false;
}
DEFINE_bool(b1, false, "bool test");
DEFINE_validator(b1, &ValidateBool);
官网说明
google::InitGoogleLogging(argv[0]);//配合gflag的?
FLAGS_log_dir="./log/";//不会自动mkdir
FLAGS_alsologtostderr = 1; // 日志同时输出到stderr
LOG(INFO) << "Hello,GLOG! to file!";
LOG(WARNING) << "hhhh,GLOG! to file!";
LOG(ERROR) << "Hello,GLOG! to file!";
//LOG(FATAL) << "Hello,GLOG! to file!";
google::ShutdownGoogleLogging();//终止
Could not create logging file: No such file or directory
你需要提前mkdir,指定的是路径不是文件名,会产出一堆文件。
$ ls log/glog_demo.
glog_demo.ERROR glog_demo.ld-TM1701.ld.log.INFO.20220325-170134.11047
glog_demo.INFO glog_demo.ld-TM1701.ld.log.WARNING.20220325-170134.11047
glog_demo.ld-TM1701.ld.log.ERROR.20220325-170134.11047 glog_demo.WARNING
一些demo和简介
官网
python2安装,到今天已经不太好用了,也有一些使用说明
python3版安装,有一些环境修改,如果出了问题,照着改回去
网络问题
改了python版本后会有后遗症,比如cmake报错
No module named ‘lsb_release’
后遗症解决
但是具体复制路径可能有区别,比如我是
sudo cp /usr/lib/python3/dist-packages/lsb_release.py /usr/local/lib/python3.7/
python3.7前边有个lib(我是手动装的python)
有时候会有kill失败,用-9可以成功
sudo apt-get install expect
功能是能自动完成ssh登录,批量写脚本操作
#!/bin/bash
#blabla, 创建要拷贝的路径和目标路径
expect -c "
set timeout -1
spawn scp ${forwardx_user}@${forwardx_host}:${bag_files} $bag_target_path
expect {
yes/no {send \"yes\r\" ;exp_continue};
password: {send \"${forwardx_pwd}\r\" };
}
expect eof
"
批量拷贝文件时候有一个问题,拷贝几个文件就会断开,而且数量不固定,原因是默认timeout 30,改成-1(无限)就好了。
写法仅供参考,正常是可以#!/usr/bin/expect -f的,但是如果要写其他逻辑,可能就用bash了,然后把expect的部分用如下代码括起来
expect -c "
do something
expect eof
"
本地合并冲突
跟踪远程分支的作用
应该是pull能自动获得同步,比如你是dev_hqw,你总要往develop上merge,你可以
git branch --set-upstream-to origin/develop
比如我当前是loc_evo,我想跟踪develop
建立分支跟踪的方法:
git branch --set-upstream-to=origin/develop
但是我发现一个弊端,因为我要申请merge,所以我不能和develop很好的联动,老提示我领先develop,让我上传(但是不能,我要申请merge),所以我要解锁
解锁不知道,可以重新指向,比如自己
git branch --set-upstream-to=origin/loc_evo
git status会显示一大堆文件变红,git diff会看到old mode new mode 错误。
这个664和755眼熟吧?当你从一个电脑把代码库复制到硬盘,复制到其他电脑,就会出这个错,一种方法可能是批量改文件权限,我觉得duck不必。
在代码库目录下,键入
git config --add core.filemode false
即可解决。。
git rebase -i HEAD~3
合并最后三个提交记录
git rebase -i hash_a hash_c
合并hash_a到hash_c的提交
假如有abcd四个提交,合并bcd为b,直接会更新到当前分支
假如有abcd四个提交,合并bc为b,则当前处于HEAD detached 游离状态,并且此状态下不存在d的提交.
现有两个选择,git checkout main_branch,丢弃rebase操作
(上接rebase游离态)
git checkout -b temp_branch
git checkout main_branch
git merge temp_branch
自己处理一下冲突,现在的提交记录是:
a new_b d
无c的记录,有c的内容,不丢d的记录
暂时无解,小米笔记本的F10通过fn+esc已经解放,笔记本键盘可以正常使用,但是高斯键盘无解。
top跟踪只跟踪一个节点
pidof cartographer_node
xxxx
top -p xxxx
update是更新源,upgrade是更新已安装软件,不要乱用。
sudo apt-get install Kolourpaint4
大小写敏感,不能用小写k,不会给你智能提示
apt-get install 自动补全
sudo apt-get install bash-completion
编辑bashrc
if [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
sudo apt install p7zip-full
-o是output,但是不加空格直接连路径
$7z x 通辽蒙牛.7z -r -o/home/ld/data/evaluating_bags/mengniu_nomap/test
rosbag info ruiming/navi_loc_2022-01-23-11-17-27.bag | grep localization_manager/status
rostopic list | grep tf
替代品,meld,或者diff,系统自带或者apt-get即可
meld不光可以对比,可以直接点箭头编辑,像代码合并一样方便
可以绑定github帐号(需要下载最新版本vscode),这样就不用每次重新下载一堆东西
vscode.cdn.azure.cn
浏览器下载deb时,替换下载链接(但是感觉很个性化,需要对应具体软件,不一定有)
vscode
方法一:
在 json 文件中添加:
方法二:
在设置中搜索format on type,勾选✔该项即可
如果你有多级目录,每级目录都有.vscodec_cpp_properties.json
为了统计文本数据,替代notepad++,有一些比如kate,搜索时能显示出结果条数。
官方的浏览器多标签看的眼瞎,只能看到当前目录名,根本分不清开的是什么
可选浏览器
还不错,标签页+链接+终端+收藏,但是默认打不开terminal,需要konsole
$ sudo apt-get install dolphin konsole
右键首选项preference,layout可以保存,自带启动指令没有测试成功,窗口测试成功,配置文件在
gedit ~/.config/terminator/config
窗口名默认难以保存,可以手动加
title = window_name
路径是
directory = /home/user1/data
### terminator
=====================================
展开查看
System.out.println("Hello to see U!");
System.out.println("Hello to see U!");
System.out.println("Hello to see U!");
System.out.println("Hello to see U!");