ROS中常见问题
- 【gazebo】
- 【ROS】
- rosdep install
- ROS中多个工作空间同时工作
- ros项目编译找不到msg/srv文件产生的头文件
- rosdep update time out及失败解决方案
- fatal error: Eigen/Geometry: No such file or directory
- Node Manager
- rospy
- xacro 与 urdf 文件检查
- rosparam单个string参数划分多个string
- nodelet 常见问题: 命名空间
- cv_bridge与opencv版本冲突
- [cartographer] absl R_X86_64_PC32 -fPIC
- 终端kill所有的ros节点与rosmater
- stdbuf + script 终端后台追加运行脚本并保存终端执行的全部log
- 使用ROS rosbag工具进行过滤(filter)操作[过滤话题,重映射,tf剪枝]
- [cartographer][升级Sphinx] exception: cannot import name 'contextfunction' from 'jinja2'
- ignore 忽略包编译
- ROS指定单独编译与恢复整体编译
- catkin_make install 出错setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
- No module named rospkg (python3)
- ROS通信模型之深度分析[知乎]
- 【ROS2】
- 【apt]】
- 【git】
- 【ubuntu】
- 【c++】
- 【cv】
- 【docker】
- 【shell】
- 【python】
【gazebo】
Spawn service failed. Exiting
**将launch文件中.world文件里的sim_time值改为0**
<sim_time>95 28000000</sim_time>
<real_time>95 520885217</real_time>
⇒ 调整为
<sim_time>0</sim_time>
<real_time>0</real_time>
gazebo模型与服务器
本地路径: ~/.gazebo/modelskint@kint:~/.gazebo/models$ pwd
/home/kint/.gazebo/models
kint@kint:~/.gazebo/models$ ls
10cm kinect
16cm kitchen_dining
3_bord ksql_airport
3_bord.zip ladder_60deg_0rails
ambulance ladder_60deg_1rails
apartment ladder_60deg_2rails
apollo15_landing_site_1000x1000 ladder_75deg_0rails
arm_part ladder_75deg_1rails
arrow_red ladder_75deg_2rails
asphalt_plane lamp_post
asus_xtion_pro_camera law_office
ball_bearing LICENSE
baylands lunar_tranquillitatis_pit
beer mailbox
bin_4_dropping_task manifest.xml.in
blackflys marble_1_5cm
bookshelf mars_rover
bowl mass_on_rails
box_target_green mcmillan_airfield
box_target_red metal_peg
breakable_test metal_peg_board
brick_box_3x1x3 monkey_wrench
bumblebee_xb3 mpl_right_arm
………………………………………………………………………………………………………………………………
house_3 wooden_board
husky wooden_case
intel_realsense_r200 wooden_case_metal_peg
iris_with_standoffs wooden_case_wooden_peg
iris_with_standoffs_demo wooden_peg
irobot_hand wooden_peg_board
iscas_museum yosemite
iss youbot
iss_half zephyr_delta_wing
jersey_barrier
1)模型存放网址
http://models.gazebosim.org/
同步到:models.gazebosim.org
wget -r -R "index\.html*" http://models.gazebosim.org/
参考: https://answers.ros.org/question/199401/problem-with-indigo-and-gazebo-22/
2)模型github 仓库,直接下载放到本地路径: ~/.gazebo/models下
https://github.com/osrf/gazebo_models
https://gitee.com/slamcn/gazebo_models
-
配置说明,服务器连接不上,直接按照12步骤下载成本地离线的,配置中去掉从服务器下载
调整GAZEBO_MODEL_DATABASE_URI为空, 本地 ~/.gazebo/models 里面 kint@kint:~/.gazebo/models.gazebosim.org$ cat /usr/share/gazebo/setup.sh export GAZEBO_MASTER_URI=http://localhost:11345 export GAZEBO_MODEL_DATABASE_URI="" # http://gazebosim.org/models export GAZEBO_RESOURCE_PATH=/usr/share/gazebo-9:${GAZEBO_RESOURCE_PATH} export GAZEBO_PLUGIN_PATH=/usr/lib/x86_64-linux-gnu/gazebo-9/plugins:${GAZEBO_PLUGIN_PATH} export GAZEBO_MODEL_PATH=/usr/share/gazebo-9/models:${GAZEBO_MODEL_PATH} export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/lib/x86_64-linux-gnu/gazebo-9/plugins export OGRE_RESOURCE_PATH=/usr/lib/x86_64-linux-gnu/OGRE-1.9.0
gazebo中添加动态障碍物 [actor]
gazebo 添加动态障碍物
gazebo添加动态障碍物插件
gazebo中动态障碍物实时pose
gazebo中模型运动快了会飘,长时间静止放置位置会飘
相关参数说明:
Gazebo 物理引擎的参数调整主要涉及到四个方面:摩擦(Friction)、惯性(Inertia)、接触(Contact)和重力(Gravity)。这些参数的调整可能会直接影响到机器人在仿真环境中的表现。
以下是针对这些参数进行调整的一些建议:
摩擦(Friction):Gazebo 的摩擦模型包括静摩擦(Static Friction)、动摩擦(Dynamic Friction)以及滚动摩擦(Rolling Friction)。
静摩擦和动摩擦可以通过 <mu> 和 <mu2> 标签进行设置,滚动摩擦则通过 <friction> 标签进行设置。
摩擦系数的设置可以影响到机器人的滑动以及旋转行为,因此如果你的机器人在快速转动或者滑动时出现问题,可能需要调整这些参数。
惯性(Inertia):惯性是物体保持其当前运动状态的性质,包括线性惯性和角动量。在 Gazebo 中,你可以通过 <inertial> 标签来设置惯性参数。
其中 <mass> 设置质量,<inertia> 设置惯性矩阵。这些参数可以影响到机器人在运动时的稳定性,例如在快速转动时是否容易翻滚或者打滑。
接触(Contact):Gazebo 中的接触参数可以设置物体之间的碰撞行为,例如反弹、摩擦以及接触力等。
这些参数可以通过 <contact> 标签进行设置,包括 <kp>、<kd>、<minDepth>、<maxVel>等。这些参数的设置可以影响到机器人在碰撞或者接触其他物体时的行为。
重力(Gravity):重力参数可以通过 <gravity> 标签进行设置。在某些情况下,你可能需要调整重力参数以便更好地模拟特定环境,例如在水下或者在空间站等。
物理引擎的更新频率(<real_time_update_rate>):这个参数控制着Gazebo物理引擎的更新速度。增大这个值可以使模拟的结果更加精确,
但是同时也会增加计算的复杂性,可能导致模拟速度下降。相反,如果降低这个值,可能会导致模拟结果的精度降低,但是可以减小计算的复杂性,从而提高模拟速度。
摩擦系数(<mu>和<mu2>):这两个参数分别控制了摩擦力模型在两个方向的摩擦系数。增大这些值将会增加摩擦力,使得模型在这个方向上的移动更困难。
相反,减小这些值将会减小摩擦力,使得模型在这个方向上的移动更容易。
接触面模型的弹性系数(<kp>)和阻尼系数(<kd>):这两个参数控制了接触面模型的弹性和阻尼特性。
弹性系数<kp>决定了接触面的弹性程度,增大它会使得接触面在受力后回弹得更快,而减小它会使得接触面在受力后回弹得更慢。
阻尼系数<kd>决定了接触面在受力后的阻尼程度,增大它会使得接触面在受力后回弹的速度更慢,而减小它会使得接触面在受力后回弹的速度更快。
//mu1 mu2 kp 的调整
<gazebo reference="wheel_left_link">
<mu1>1.0</mu1>
<mu2>1.0</mu2>
<kp>100000.0</kp>
<kd>10.0</kd>
<minDepth>0.001</minDepth>
<maxVel>1.5</maxVel>
<fdir1>1 0 0</fdir1>
<material>Gazebo/FlatBlack</material>
</gazebo>
<gazebo reference="wheel_right_link">
<mu1>1.0</mu1>
<mu2>1.0</mu2>
<kp>100000.0</kp>
<kd>10.0</kd>
<minDepth>0.001</minDepth>
<maxVel>1.5</maxVel>
<fdir1>1 0 0</fdir1>
<material>Gazebo/FlatBlack</material>
</gazebo>
docker 中启动gazebo
xhost +local:root
docker run -itd --name=ros2_humble --net=host --privileged -e DISPLAY=$DISPLAY --gpus all --env="NVIDIA_DRIVER_CAPABILITIES=all" --volume="$HOME/.Xauthority:/root/.Xauthority:rw" -v /etc/timezone:/etc/timezone:ro -v /etc/localtime:/etc/localtime:ro -v /home/robot:/home/robot -v /home/robot/.gazebo/models:/root/.gazebo/models -v /tmp/.X11-unix:/tmp/.X11-unix -v $HOME/.Xauthority:/root/.Xauthority:rw --device=/dev/bus/usb:/dev/bus/usb d9aa388a3dea /bin/bash;;
docker run -itd --name=ros2_humble --net=host --privileged -e DISPLAY=unix$DISPLAY -e GDK_SCALE -e GDK_DPI_SCALE --volume="$HOME/.Xauthority:/root/.Xauthority:rw" -v /etc/timezone:/etc/timezone:ro -v /etc/localtime:/etc/localtime:ro -v /home/robot:/home/robot -v /home/robot/.gazebo/models:/root/.gazebo/models -v /tmp/.X11-unix:/tmp/.X11-unix -v $HOME/.Xauthority:/root/.Xauthority:rw --device=/dev/bus/usb:/dev/bus/usb d9aa388a3dea /bin/bash;;
【ROS】
rosdep install
rosdep install --from-paths src --ignore-src
ROS中多个工作空间同时工作
因为在catkin_make时,会检查编译时的ROS环境并记录下来,保存在work1_ws /devel/_setup_util.py python文件的CMAKE_PREFIX_PATH变量中。
以后在执行这个工作空间的setup.bash脚本时,会使用编译时的状态覆盖ROS_PACKAGE_PATH的值。
ros项目编译找不到msg/srv文件产生的头文件
一般情况下,如果你的msg/srv文件是一个单独的package的话(假设为A),在依赖A生成的头文件的packageB里面编译对应的cpp文件时,
在add_dependencies的最后添加${catkin_EXPORTED_TARGETS}会包含所有在find_package里面列出的包的_generate_messages_cpp宏用来生成对应的头文件,这样编译应该是没有问题的。
但是当msg/srv和需要其产生头文件的cpp文件在同一个包里面时,第一次编译会报找不到头文件的错,在${catkin_EXPORTED_TARGETS}这个宏之前再加一个current_package_generate_messages_cpp,current_package换成当前的包名即可
rosdep update time out及失败解决方案
参考rosdep update失败的解决方法
第三种本地化离线方式处理:
- clone rosdistro 到本地
mkdir -p ~/.ros/rosdep
cd ~/.ros/rosdep
git clone https://github.com/ros/rosdistro
修改本地repo内链接
cat rosdep/sources.list.d/20-default.list
yaml file:///home/robot/.ros/rosdep/rosdistro/rosdep/osx-homebrew.yaml osx
# generic
yaml file:///home/kint/.ros/rosdep/rosdistro/rosdep/base.yaml
yaml file:///home/kint/.ros/rosdep/rosdistro/rosdep/python.yaml
yaml file:///home/kint/.ros/rosdep/rosdistro/rosdep/ruby.yaml
gbpdistro file:///kint/robot/.ros/rosdep/rosdistro/releases/fuerte.yaml fuerte
# newer distributions (Groovy, Hydro, ...) must not be listed anymore, they are being fetched from the rosdistro index.yaml instead
- 修改 20-default.list 连接为本地下载的rosdistro 里面的对应文件
将文件中的网址https://raw.githubusercontent.com/ros/rosdistro/master修改为下载目录file:///home/xxx/rosdistro
sudo vim /etc/ros/rosdep/sources.list.d/20-default.list
yaml file:///home/kint/.ros/rosdep/rosdistro/rosdep/osx-homebrew.yaml osx
#generic
yaml file:///home/kint/.ros/rosdep/rosdistro/rosdep/base.yaml
yaml file:///home/kint/.ros/rosdep/rosdistro/rosdep/python.yaml
yaml file:///home/kint/.ros/rosdep/rosdistro/rosdep/ruby.yaml
gbpdistro file:///home/kint/.ros/rosdep/rosdistro/releases/fuerte.yaml fuerte
#yaml https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/base.yaml
#yaml https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/python.yaml
#yaml https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/ruby.yaml
#gbpdistro https://raw.githubusercontent.com/ros/rosdistro/master/releases/fuerte.yaml fuerte
#newer distributions (Groovy, Hydro, ...) must not be listed anymore, they are being fetched from the rosdistro index.yaml instead
- 修改sources_list.py文件
sudo gedit /usr/lib/python2.7/dist-packages/rosdep2/sources_list.py
#DEFAULT_SOURCES_LIST_URL = 'https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/sources.list.d/20-default.list'
DEFAULT_SOURCES_LIST_URL = 'file:///etc/ros/rosdep/sources.list.d/20-default.list'
- 修改rep3.py
sudo gedit /usr/lib/python2.7/dist-packages/rosdep2/rep3.py
REP3_TARGETS_URL = 'file:///home/kint/.ros/rosdep/rosdistro/releases/targets.yaml'
#REP3_TARGETS_URL = 'https://raw.githubusercontent.com/ros/rosdistro/master/releases/targets.yaml'
- . 修改_init_.py文件
sudo gedit /usr/lib/python2.7/dist-packages/rosdistro/__init__.py
DEFAULT_INDEX_URL = 'file:///home/kint/.ros/rosdep/rosdistro/index-v4.yaml'
#DEFAULT_INDEX_URL = 'https://raw.githubusercontent.com/ros/rosdistro/master/index-v4.yaml'
- 重新更新
sudo rosdep init
如果20-default.list 已经存在,可以先删除,再执行一遍sudo rosdep init
rosdep update
---------正确更新的log
kint@kint:~/.ros/rosdep$ rosdep update
reading in sources list data from /etc/ros/rosdep/sources.list.d
Hit file:///home/kint/.ros/rosdep/rosdistro/rosdep/osx-homebrew.yaml
Hit file:///home/kint/.ros/rosdep/rosdistro/rosdep/base.yaml
Hit file:///home/kint/.ros/rosdep/rosdistro/rosdep/python.yaml
Hit file:///home/kint/.ros/rosdep/rosdistro/rosdep/ruby.yaml
Hit file:///home/kint/.ros/rosdep/rosdistro/releases/fuerte.yaml
Query rosdistro index file:///home/kint/.ros/rosdep/rosdistro/index-v4.yaml
Skip end-of-life distro "ardent"
Skip end-of-life distro "bouncy"
Skip end-of-life distro "crystal"
Skip end-of-life distro "dashing"
Skip end-of-life distro "eloquent"
Add distro "foxy"
Add distro "galactic"
Skip end-of-life distro "groovy"
Add distro "humble"
Skip end-of-life distro "hydro"
Skip end-of-life distro "indigo"
Skip end-of-life distro "jade"
Skip end-of-life distro "kinetic"
Skip end-of-life distro "lunar"
Add distro "melodic"
Add distro "noetic"
Add distro "rolling"
updated cache in /home/kint/.ros/rosdep/sources.cache
-----------------
ubuntu 22.04对应python3相关的
下载rosdep到本地
mkdir -p ~/.ros/rosdep
cd ~/.ros/rosdep
git clone git@github.com:ros/rosdistro.git
修改repo内链接
robot@robot:~/.ros/rosdep/rosdistro$ git status
modified: rosdep/sources.list.d/20-default.list
robot@robot:~/.ros/rosdep/rosdistro$ git diff
diff --git a/rosdep/sources.list.d/20-default.list b/rosdep/sources.list.d/20-default.list
index fb6744c4d..d232d62af 100644
--- a/rosdep/sources.list.d/20-default.list
+++ b/rosdep/sources.list.d/20-default.list
@@ -1,10 +1,10 @@
-# os-specific listings first
-yaml https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/osx-homebrew.yaml osx
+
+yaml file:///home/robot/.ros/rosdep/rosdistro/rosdep/osx-homebrew.yaml osx
# generic
-yaml https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/base.yaml
-yaml https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/python.yaml
-yaml https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/ruby.yaml
-gbpdistro https://raw.githubusercontent.com/ros/rosdistro/master/releases/fuerte.yaml fuerte
-
-# newer distributions (Groovy, Hydro, ...) must not be listed anymore, they are being fetched from the rosdistro index.yaml instead
+yaml file:///home/robot/.ros/rosdep/rosdistro/rosdep/base.yaml
+yaml file:///home/robot/.ros/rosdep/rosdistro/rosdep/python.yaml
+yaml file:///home/robot/.ros/rosdep/rosdistro/rosdep/ruby.yaml
+gbpdistro file:///home/robot/.ros/rosdep/rosdistro/releases/fuerte.yaml fuerte
+
+# newer distributions (Groovy, Hydro, ...) must not be listed anymore, they are being fetched from the rosdistro index.yaml instead
\ No newline at end of file
cat rosdep/sources.list.d/20-default.list
yaml file:///home/robot/.ros/rosdep/rosdistro/rosdep/osx-homebrew.yaml osx
# generic
yaml file:///home/robot/.ros/rosdep/rosdistro/rosdep/base.yaml
yaml file:///home/robot/.ros/rosdep/rosdistro/rosdep/python.yaml
yaml file:///home/robot/.ros/rosdep/rosdistro/rosdep/ruby.yaml
gbpdistro file:///home/robot/.ros/rosdep/rosdistro/releases/fuerte.yaml fuerte
# newer distributions (Groovy, Hydro, ...) must not be listed anymore, they are being fetched from the rosdistro index.yaml instead
修改链接为本地
sudo gedit /etc/ros/rosdep/sources.list.d/20-default.list
yaml file:///home/robot/.ros/rosdep/rosdistro/rosdep/osx-homebrew.yaml osx
# generic
yaml file:///home/robot/.ros/rosdep/rosdistro/rosdep/base.yaml
yaml file:///home/robot/.ros/rosdep/rosdistro/rosdep/python.yaml
yaml file:///home/robot/.ros/rosdep/rosdistro/rosdep/ruby.yaml
gbpdistro file:///home/robot/.ros/rosdep/rosdistro/releases/fuerte.yaml fuerte
# newer distributions (Groovy, Hydro, ...) must not be listed anymore, they are being fetched from the rosdistro index.yaml instead
sudo gedit /usr/lib/python3/dist-packages/rosdep2/sources_list.py
#DEFAULT_SOURCES_LIST_URL = 'https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/sources.list.d/20-default.list'
DEFAULT_SOURCES_LIST_URL = 'file:///home/robot/.ros/rosdep/rosdistro/rosdep/sources.list.d/20-default.list'
sudo gedit /usr/lib/python3/dist-packages/rosdep2/rep3.py
#REP3_TARGETS_URL = 'https://raw.githubusercontent.com/ros/rosdistro/master/releases/targets.yaml'
REP3_TARGETS_URL = 'file:///home/robot/.ros/rosdep/rosdistro/releases/targets.yaml'
sudo gedit /usr/lib/python3/dist-packages/rosdistro/init.py
#DEFAULT_INDEX_URL = 'https://raw.githubusercontent.com/ros/rosdistro/master/index-v4.yaml'
DEFAULT_INDEX_URL = 'file:///home/robot/.ros/rosdep/rosdistro/index-v4.yaml'
命令更新
sudo rm /etc/ros/rosdep/sources.list.d/20-default.list
sudo rosdep init
rosdep update
成功输出:
robot@robot:~$ rosdep update
reading in sources list data from /etc/ros/rosdep/sources.list.d
Hit file:///home/robot/.ros/rosdep/rosdistro/rosdep/osx-homebrew.yaml
Hit file:///home/robot/.ros/rosdep/rosdistro/rosdep/base.yaml
Hit file:///home/robot/.ros/rosdep/rosdistro/rosdep/python.yaml
Hit file:///home/robot/.ros/rosdep/rosdistro/rosdep/ruby.yaml
Hit file:///home/robot/.ros/rosdep/rosdistro/releases/fuerte.yaml
Query rosdistro index file:///home/robot/.ros/rosdep/rosdistro/index-v4.yaml
Skip end-of-life distro "ardent"
Skip end-of-life distro "bouncy"
Skip end-of-life distro "crystal"
Skip end-of-life distro "dashing"
Skip end-of-life distro "eloquent"
Skip end-of-life distro "foxy"
Skip end-of-life distro "galactic"
Skip end-of-life distro "groovy"
Add distro "humble"
Skip end-of-life distro "hydro"
Skip end-of-life distro "indigo"
Add distro "iron"
Skip end-of-life distro "jade"
Skip end-of-life distro "kinetic"
Skip end-of-life distro "lunar"
Skip end-of-life distro "melodic"
Add distro "noetic"
Add distro "rolling"
updated cache in /home/robot/.ros/rosdep/sources.cache
fatal error: Eigen/Geometry: No such file or directory
ref
创建软链接
cd /usr/include
sudo ln -sf eigen3/Eigen Eigen
sudo ln -sf eigen3/unsupported unsupported
Node Manager
参考:https://github.com/fkie/multimaster_fkie/wiki
Installation via apt
melodic and older: sudo apt install ros-melodic-multimaster-fkie
noetic and newer: sudo apt install ros-noetic-fkie-multimaster (Note: Currently broken, issue here)
node_manager
rospy
1. rospy模块导入 Import Python Module From Another Package
解决思路: 导出python执行文件与模块到对应的ROS全局命名空间内的新package中
文件目录:
robot_helper
├── api
│ ├── api.py
│ ├── api2.py
│ ├── my_test_exe
│ └── __init__.py
├── scripts
│ ├── manager.py
├── package.xml
├── CMakeLists.txt
├── setup.py
具体文件内容:
#And inside the api.py, you have some class
class MY_API():
def __init__(self):
#And inside the api2.py, you have some class
class MY_API2():
def __init__(self):
1. 在api文件夹中创建空文件 __init__.py
2. 创建文件 setup.py
3. 在 CMakeLists.txt 文件中,find_package后加入 catkin_python_setup()
## Uncomment if the package has a setup.py
catkin_python_setup()
4. 完成文件setup.py
from distutils.core import setup
from catkin_pkg.python_setup import generate_distutils_setup
setup_args = generate_distutils_setup(
packages=['my_api'],
package_dir={'': 'api'}
)
setup(**setup_args)
5. 在 CMakeLists.txt 文件中加入install
# catkin_install_python(PROGRAMS api/my_test_exe
# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
说明setup.py:
1. CMakeLists.txt 文件中catkin_python_setup() 会对应执行 run setup.py.
2. __init__.py 将文件夹内容暴露给setup.py
3. packages=['my_api'] 让ROS找到 python package.
4. package_dir={'': 'api'} 告诉ROS将对应api文件夹的所有python文件作为全局python环境
Python文件导入测试: api,api2 对应my_api包中api.py api2.py文件
from api import MY_API
from api2 import MY_API2
xacro 与 urdf 文件检查
xacro的urdf检查需要先转化为urdf文件
rosrun xacro xacro test.xacro > test.urdf # 格式转化
check_urdf racecar.urdf.urdf #语法检查,输出关系或错误
urdf_to_graphiz racecar.urdf.urdf # 可视化输出树形结构
rosparam单个string参数划分多个string
借助std::stringstream 是 C++ 中的一个类,提供了一个输入/输出流接口,用于将内存中的字符串缓冲区视为流进行读写操作。它可以用于从字符串中读取输入,或将输出写入到字符串中。
std::string topics_string;
// get the topics that we'll subscribe to from the parameter server
node_handle.param("topics_string", topics_string, std::string(""));
LOG(INFO)<<" topics_string: "<<topics_string;
std::stringstream ss(topics_string);
std::string source;
while (ss >> source)
{
LOG(INFO)<<"source: "<<source;
}
<node pkg="xx" type="xx" name="xx" output="screen">
<param name="topics_string" type="string" value="name1 name2 name3 "/>
</node>
I0224 16:57:24.099885 21613 xx.cpp:14] topics_string: name1 name2 name3
I0224 16:57:24.100028 21613 xx.cpp:20] source: name1
I0224 16:57:24.100047 21613 xx.cpp:20] source: name2
I0224 16:57:24.100056 21613 xx.cpp:20] source: name3
nodelet 常见问题: 命名空间
nodelet说明参照: https://robkin.blog.csdn.net/article/details/52143309
- 正常node程序改写成nodelet
参照nodelet的说明, 注意点:
CMakeLists.txt:
find_package: pluginlib nodelet
catkin_package(
INCLUDE_DIRS include
LIBRARIES berxel_camera_nodelet
CATKIN_DEPENDS pluginlib nodelet
)
# add xml file
install(FILES berxel_nodelets.xml
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
)
install(TARGETS ${PROJECT_NAME} berxel_camera_nodelet
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
package.xml
<build_depend>nodelet</build_depend>
<build_depend>pluginlib</build_depend>
<exec_depend>nodelet</exec_depend>
<exec_depend>pluginlib</exec_depend>
<export>
<nodelet plugin="${prefix}/berxel_nodelets.xml"/>
</export>
berxel_nodelets.xml
<library path="lib/libberxel_camera_nodelet">
<class name="CameraNodelet" type="CameraNodelet" base_class_type="nodelet::Nodelet">
<description>
Astra camera driver nodelet.
</description>
</class>
</library>
cpp文件
#include <ros/ros.h>
#include <pluginlib/class_list_macros.h>
#include <nodelet/nodelet.h>
#include "BerxelHawkCamera.h"
class CameraNodelet : public nodelet::Nodelet {
public:
CameraNodelet() : running_(false) {}
~CameraNodelet();
private:
virtual void onInit();
volatile bool running_;
boost::shared_ptr<BerxelHawkCamera> driver_;
};
CameraNodelet::~CameraNodelet() {
if (running_) {
std::cout<<"~CameraNodelet"<<std::endl;
}
}
void CameraNodelet::onInit() {
ros::NodeHandle nh(getNodeHandle());
ros::NodeHandle priv_nh(getPrivateNodeHandle());
driver_.reset(new BerxelHawkCamera(nh, priv_nh));
driver_->initBerxelCamera();
}
// Register this plugin with pluginlib.
// parameters are: class type, base class type
PLUGINLIB_EXPORT_CLASS(CameraNodelet, nodelet::Nodelet)
-
找不到nodelet插件,请检查1里面相关的设置.
rospack plugins --attrib=plugin nodelet
berxel_camera ~/xx_ws/install/share/berxel_camera/berxel_nodelets.xml -
node节点与命名空间的关系
n2(“~”) 对应manager的空间; getPrivateNodeHandle()对应节点CameraFilterLeft的空间;
nh 与 getNodeHandle() 也存在一定的差异.
建议具体实现类的node_handle都以nodelet中获取的getPrivateNodeHandle()和getNodeHandle()创建并传下去。
launch文件中:
<node pkg="nodelet" type="nodelet" name="berxel_left_camera_manager" args="manager" output="screen"/>
<node pkg="nodelet" type="nodelet" name="CameraFilterLeft" args="load CameraFilterNodelet berxel_left_camera_manager" output="screen"、>
分清楚这个几个命名空间的对应:
void CameraFilterNodelet::onInit() {
ros::NodeHandle nh(getNodeHandle());
ros::NodeHandle priv_nh(getPrivateNodeHandle());
ros::NodeHandle node = this->getPrivateNodeHandle();
std::cout<<"==>>>>>>>>CameraFilterNodeletonInit1: nh: "<<nh.getNamespace()<<std::endl;
std::cout<<"==>>>>>>>>CameraFilterNodeletonInit1: priv_nh: "<<priv_nh.getNamespace()<<std::endl;
std::cout<<"==>>>>>>>>CameraFilterNodeletonInit1: node: "<<node.getNamespace()<<std::endl;
ros::NodeHandle n1;
ros::NodeHandle n2("~");
std::cout<<"==>>>>>>>>CameraFilterNodeletonInit1: n1: "<<n1.getNamespace()<<std::endl;
std::cout<<"==>>>>>>>>CameraFilterNodeletonInit1: n2: "<<n2.getNamespace()<<std::endl;
cam_filter_.reset(new CameraFilter(nh, priv_nh));
running_ = true;
}
=======输出:
==>>>>>>>>CameraFilterNodeletonInit1: nh:
==>>>>>>>>CameraFilterNodeletonInit1: priv_nh: /CameraFilterLeft
==>>>>>>>>CameraFilterNodeletonInit1: node: /CameraFilterLeft
==>>>>>>>>CameraFilterNodeletonInit1: n1: /
==>>>>>>>>CameraFilterNodeletonInit1: n2: /berxel_left_camera_manager
==>>>>>>>>CameraFilter: n1: /
==>>>>>>>>CameraFilter: n2: /berxel_left_camera_manager
- nodelet节点与dynamic_reconfigure命名空间的关系
其实也是3对应的命名空间问题,记得将nh传入, 不然默认是(“~”)
dsrv_ = new dynamic_reconfigure::Server<depth_camera::calib_paramConfig>(private_nh_);
cv_bridge与opencv版本冲突
问题:
编译正常,有warning, 运行时部分函数报错
/usr/bin/ld: warning: libopencv_imgproc.so.3.4, needed by /usr/local/lib/libopencv_highgui.so.3.4.18, may conflict with libopencv_imgproc.so.3.2
OpenCV Error: Bad argument (Unknown interpolation method) in resize, file /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/imgproc/src/imgwarp.cpp, line 3367
terminate called after throwing an instance of 'cv::Exception'
what(): /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/imgproc/src/imgwarp.cpp:3367: error: (-5) Unknown interpolation method in function resize
解决方式:
ref
修改cv_bridge指定的opencv版本。修改指定的include与libs
sudo gedit /opt/ros/melodic/share/cv_bridge/cmake/cv_bridgeConfig.cmake
#if(NOT "include;/usr/include;/usr/include/opencv " STREQUAL " ")
if(NOT "include;/usr/local/include/opencv;/usr/local/include/opencv2 " STREQUAL " ")
set(cv_bridge_INCLUDE_DIRS "")
#set(_include_dirs "include;/usr/include;/usr/include/opencv")
set(_include_dirs "include;/usr/local/lib;/usr/local/include/opencv;/usr/local/include/opencv2;/usr/local/include;/usr/include")
#set(libraries "cv_bridge;/usr/lib/x86_64-linux-gnu/libopencv_core.so.3.2.0;/usr/lib/x86_64-linux-gnu/libopencv_imgproc.so.3.2.0;/usr/lib/x86_64-linux-gnu/libopencv_imgcodecs.so.3.2.0")
set(libraries "cv_bridge;/usr/local/lib/libopencv_core.so.3.4.18;/usr/local/lib/libopencv_imgproc.so.3.4.18;/usr/local/lib/libopencv_imgcodecs.so.3.4.18")
[cartographer] absl R_X86_64_PC32 -fPIC
编译cartographer_rviz遇到问题
[100%] Linking CXX shared library /home/firefly/RenBot_ws/devel/lib/libcartographer_rviz.so
/usr/bin/ld: /usr/local/lib/libabsl_synchronization.a(mutex.cc.o): relocation R_X86_64_PC32 against symbol `_ZNSt11this_thread5yieldEv' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
参考:relocation R_X86_64_PC32 against symbol can not be used when making a shared object; recompile with -fPIC
编译cartographer_rviz出现libabsl_synchronization.a库错误
在安装abseil的cmakelist.txt文件中加入, 重新编译安装abseil库就可以了
set(CMAKE_BUILD_TYPE "Release")
SET( CMAKE_CXX_FLAGS "-std=c++11 -O3")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -fPIC")
RUN cd ~/carto_libs/abseil-cpp && \
mkdir -p build && \
cd build && \
cmake .. -DCXX11=ON && \
make -j16 && \
make install >> ../install.info && \
echo "Finish ceres"
stowing bar would cause conflicts:
WARNING! stowing bar would cause conflicts:
* existing target is neither a link nor a directory: foo
All operations aborted.
sudo stow --adopt absl
终端kill所有的ros节点与rosmater
rosnode kill -a && pkill rosmaster
stdbuf + script 终端后台追加运行脚本并保存终端执行的全部log
roscore_pid=-1
stdbuf -oL -eL script -a -f -c "roscore" /tmp/roscore.log &
roscore_pid=$!
if [ $roscore_pid -gt 0 ]; then
wait $roscore_pid
fi
stdbuf 是一个用于调整另一个程序缓冲区的命令行工具。-oL -eL 参数表示将输出(stdout)和错误输出(stderr)设置为行缓冲模式(每行立即刷新缓冲区,而不是等待缓冲区满)。
script 命令用于将终端会话记录到文件中。-a 参数表示追加输出到文件,而不是覆盖文件。-f 参数表示将输出立即刷新到文件。-c 参数后跟要执行的命令。
因此,stdbuf -oL -eL script -a -f -c “” 的意义是:
1. 使用行缓冲模式执行命令 <command>,即每行立即刷新 stdout 和 stderr 缓冲区。
2. 使用 script 命令将 <command> 的输出记录到文件中。
3. 输出将追加到文件中,而不是覆盖文件。
4. 输出将立即刷新到文件中。
这个命令组合通常用于在执行过程中实时捕获和记录命令的输出,而不是在命令完成后将输出写入文件。这在需要实时监控日志文件的场景中非常有用。
使用ROS rosbag工具进行过滤(filter)操作[过滤话题,重映射,tf剪枝]
使用ROS rosbag工具进行过滤(filter)操作[过滤话题,重映射,tf剪枝]
[cartographer][升级Sphinx] exception: cannot import name ‘contextfunction’ from ‘jinja2’
Extension error:
Could not import extension sphinx.builders.latex (exception: cannot import name 'contextfunction' from 'jinja2' (/home/robot/.local/lib/python3.8/site-packages/jinja2/__init__.py))
pip3 install --upgrade Sphinx
>>> import sphinx as sphinx
>>> sphinx.__version__
'1.8.5'
升级后
>>> import sphinx as sphinx
>>> sphinx.__version__
'7.0.0'
ignore 忽略包编译
在不想被编译的package路径下新建一个文件名为CATKIN_IGNORE的文件
ROS指定单独编译与恢复整体编译
单独包编译:
catkin_make -DCATKIN_WHITELIST_PACKAGES="具体的package"
取消指定单独包编译
catkin_make -DCATKIN_WHITELIST_PACKAGES=""
catkin_make install 出错setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] …]
catkin_make install
''''''''''''''''''''''''''''''''''''''''''''''''''''
+ cd /home/robot/work_pj/RenBot_ws/src/navigation/base_local_planner
+ mkdir -p /home/robot/work_pj/RenBot_ws/install/lib/python3/dist-packages
+ /usr/bin/env PYTHONPATH=/home/robot/work_pj/RenBot_ws/install/lib/python3/dist-packages:/home/robot/work_pj/RenBot_ws/build/lib/python3/dist-packages:/opt/ros/noetic/lib/python3/dist-packages CATKIN_BINARY_DIR=/home/robot/work_pj/RenBot_ws/build /usr/bin/python3 /home/robot/work_pj/RenBot_ws/src/navigation/base_local_planner/setup.py build --build-base /home/robot/work_pj/RenBot_ws/build/navigation/base_local_planner install --root=/ --install-layout=deb --prefix=/home/robot/work_pj/RenBot_ws/install --install-scripts=/home/robot/work_pj/RenBot_ws/install/bin
usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
or: setup.py --help [cmd1 cmd2 ...]
or: setup.py --help-commands
or: setup.py cmd --help
error: option --install-layout not recognized
CMake Error at navigation/base_local_planner/catkin_generated/safe_execute_install.cmake:4 (message):
execute_process(/home/robot/work_pj/RenBot_ws/build/navigation/base_local_planner/catkin_generated/python_distutils_install.sh)
returned error code
Call Stack (most recent call first):
navigation/base_local_planner/cmake_install.cmake:41 (include)
cmake_install.cmake:174 (include)
make: *** [Makefile:86: install] Error 1
ref:https://github.com/ros/catkin/issues/863
catkin_make install -DSETUPTOOLS_DEB_LAYOUT=OFF
catkin_make install
No module named rospkg (python3)
import rospy出错
run ROS on Ubuntu 20.04:
sudo apt-get install python3-rospkg
sudo apt install python-is-python3
ROS通信模型之深度分析[知乎]
一个节点注册它的发布或订阅的话题到master节点,每一个话题publisher通过registerPublisher()的远程过程调用注册到Master节点,每一个话题的subscriber通过registerSubscriber()的远程过程调用注册到Master。Master通过同一个话题连接发布者和订阅者。
当一个节点向master注册它的订阅话题成功时,master会返回一个包含发布者URIs信息的应答。因此subscriber和publisher就可以建立连接,之后就可以传输数据。当一个新的publishser注册到master后,master会启动publisherUpdate()通知所有的subscriber更新可用的publisher的URI列表,之后数据流就可以通过TCPROS进行交换。
与之对应的是注销过程。publisher通过unregisterPublisher()远程过程调用通知master注销自己。subscribers通过unregisterSubscriber远程过程调用通知master注销自己。是否关闭任何已建立的数据流取决于publisher和subscriber本身。
Services工作方式与话题略有不同,同一个服务能被多个节点注册,但只有最后一个起作用。节点在调用service时,通过lookupService远程过程调用,在master处查找与之对应的service的URI。之后通过相应的请求消息来通知service提供方。service提供方处理这个请求,如果请求成功会返回一个应答,如果失败则会返回一个错误信息。这些消息都是通过头部附加成功与否的标志信息的TCPROS协议实现的。
【ROS2】
rosidl_cmake/cmake/rosidl_generate_interfaces.cmake:240 (list)
工作空间路径有中文
ros2可以将自定义消息与当前程序放在同一个package里面
rosidl_target_interfaces(talker ${PROJECT_NAME} “rosidl_typesupport_cpp”)
rosidl_target_interfaces是一个CMake宏,其主要目的是为指定的目标(在这个例子中是talker)链接与消息、服务或操作相关的头文件和其他必需资源。
在ROS 2中,当你创建自定义的消息、服务或操作时,一组代码会被自动生成以支持这些接口的ROS 2使用。这包括C++头文件、Python模块和其他一些必需的资源。为了确保你的节点或库可以找到并使用这些生成的资源,你需要用rosidl_target_interfaces来链接它们。
具体到该命令的三个参数:
talker: 这是您要链接的目标。在这个例子中,它是我们的可执行文件。
${PROJECT_NAME}: 通常代表包名称,它告诉宏哪些消息、服务或操作要链接。
"rosidl_typesupport_cpp": 这指定了要链接的接口类型的支持。在这种情况下,我们要链接C++的类型支持。
简而言之,rosidl_target_interfaces确保你的节点或库正确地链接到了所有必需的消息、服务或操作的生成代码,以便在运行时正确工作。
···humble
get_default_rmw_implementation(rmw_implementation)
find_package("${rmw_implementation}" REQUIRED)
get_rmw_typesupport(typesupport_impls "${rmw_implementation}" LANGUAGE "cpp")
add_library(aa src/aa.cpp)
ament_target_dependencies(aa rclcpp std_msgs geometry_msgs )
rosidl_get_typesupport_target(aa ${PROJECT_NAME} ${typesupport_impls} )
简化的例程,演示如何在同一个ROS 2包中定义和使用自定义消息
简化的例程,演示如何在同一个ROS 2包中定义和使用自定义消息
1. 创建一个新的ROS 2包
bash
ros2 pkg create my_custom_msg_pkg --build-type ament_cmake --dependencies rclcpp std_msgs
2. 在新创建的包目录中,创建一个消息目录和消息定义
bash
cd my_custom_msg_pkg
mkdir msg
echo "string data" > msg/MyMessage.msg
3. 修改package.xml添加消息生成的依赖关系
xml
<build_depend>rosidl_default_generators</build_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>
4. 在CMakeLists.txt中启用消息生成
cmake
find_package(rosidl_default_generators REQUIRED)
set(msg_files "msg/MyMessage.msg")
rosidl_generate_interfaces(${PROJECT_NAME} ${msg_files})
5. 添加一个简单的C++节点,使用这个消息
在src目录中创建一个talker.cpp:
cpp
#include "rclcpp/rclcpp.hpp"
#include "my_custom_msg_pkg/msg/my_message.hpp"
int main(int argc, char **argv)
{
rclcpp::init(argc, argv);
auto node = std::make_shared<rclcpp::Node>("talker");
auto publisher = node->create_publisher<my_custom_msg_pkg::msg::MyMessage>("chatter", 10);
rclcpp::Rate rate(1); // 1 Hz
while (rclcpp::ok())
{
my_custom_msg_pkg::msg::MyMessage msg;
msg.data = "Hello, ROS 2!";
publisher->publish(msg);
rclcpp::spin_some(node);
rate.sleep();
}
rclcpp::shutdown();
return 0;
}
然后在CMakeLists.txt中添加编译这个节点的指令:
cmake
add_executable(talker src/talker.cpp)
ament_target_dependencies(talker rclcpp my_custom_msg_pkg)
rosidl_target_interfaces(talker ${PROJECT_NAME} "rosidl_typesupport_cpp")
6. 构建和运行
保存所有更改并返回到工作区根目录,然后运行:
bash
colcon build --packages-select my_custom_msg_pkg
. install/setup.bash
ros2 run my_custom_msg_pkg talker
您应该会看到talker节点发送的消息。
ros2 action 创建demo
ref:
ros2_action_demo
ros2 编译时提示 CATKIN_INSTALL_INTO_PREFIX_ROOT 与 CATKIN_SYMLINK_INSTALL
CMake Warning:
Manually-specified variables were not used by the project:
CATKIN_INSTALL_INTO_PREFIX_ROOT
CATKIN_SYMLINK_INSTALL
package.xml文件中添加
<export>
<build_type>ament_cmake</build_type>
</export>
ros2查看包文件与AMENT_PREFIX_PATH环境变量
ros2 pkg list | grep xxx
echo $AMENT_PREFIX_PATH
/home/robot/ws/install/xxx:/opt/ros/humble
Compilation Error: missing: GRAPHICSMAGICKCPP_INCLUDE_DIRS
rosdep install -y -r -q --from-paths src --ignore-src --rosdistro dashing -y
colcon build --symlink-install
【apt]】
1. dpkg: error processing package install-info
sudo mv /var/lib/dpkg/info/install-info.postinst /var/lib/dpkg/info/install-info.postinst.bad
【git】
1. git 状态栏中文可视化,配置
git config --global core.quotepath false
2. github --> xxxcsdner
xxxcsdner
https://raw.hellogithub.com/
【ubuntu】
1. apt update can not resolve the sources -> dns
Failed to fetch http://mirrors.ustc.edu.cn/ubuntu-ports/dists/xenial/InRelease Could not resolve ‘mirrors.ustc.edu.cn’
查看/etc/apt/sources.list 源文件,网页测试是否可以打开对应网址
$ cat /etc/apt/sources.list (ubuntu rk3399环境)
deb http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial main multiverse restricted universe
deb http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial-backports main multiverse restricted universe
deb http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial-proposed main multiverse restricted universe
deb http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial-security main multiverse restricted universe
deb http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial-updates main multiverse restricted universe
deb-src http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial main multiverse restricted universe
deb-src http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial-backports main multiverse restricted universe
deb-src http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial-proposed main multiverse restricted universe
deb-src http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial-security main multiverse restricted universe
deb-src http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial-updates main multiverse restricted universe
如果可以打开,基本是dns问题导致终端无法解析
sudo vim /etc/resolv.conf
------------------------------
nameserver 127.0.1.1
#这里用的是阿里云的DNS服务器
nameserver 223.5.5.5
nameserver 223.6.6.6
2. udev 中video端口映射
video usb hub Using multiple cameras
usb hub参考
#ls /dev/video*
/dev/video0 /dev/video1
$ udevadm info --query=all --attribute-walk --name=/dev/video0
looking at device '/devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/video4linux/video0':
KERNEL=="video0"
SUBSYSTEM=="video4linux"
DRIVER==""
ATTR{dev_debug}=="0"
ATTR{index}=="0"
ATTR{name}=="Integrated Camera: Integrated C"
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0':
KERNELS=="1-8:1.0"
SUBSYSTEMS=="usb"
DRIVERS=="uvcvideo"
....
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-8':
KERNELS=="1-8"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{authorized}=="1"
ATTRS{avoid_reset_quirk}=="0"
....
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1':
KERNELS=="usb1"
SUBSYSTEMS=="usb"
....
looking at parent device '/devices/pci0000:00/0000:00:14.0':
KERNELS=="0000:00:14.0"
SUBSYSTEMS=="pci"
DRIVERS=="xhci_hcd"
....
ATTRS{subsystem_device}=="0x2279"
ATTRS{subsystem_vendor}=="0x17aa"
ATTRS{vendor}=="0x8086"
创建 video_usb.rules文件
KERNEL=="video*", KERNELS=="5-1.2", MODE:="0777",SYMLINK+="video_m"
KERNEL=="video*", KERNELS=="5-1.3", MODE:="0777",SYMLINK+="video_r"
KERNEL=="video*", KERNELS=="5-1.4", MODE:="0777",SYMLINK+="video_l"
sudo cp video_usb.rules /etc/udev/rules.d
sudo udevadm control --reload-rules
查看设备序列号:
kint@kint:~$ lsusb -t
/: Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 10000M
/: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 480M
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/6p, 10000M
|__ Port 3: Dev 2, If 0, Class=Hub, Driver=hub/4p, 5000M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/12p, 480M
|__ Port 3: Dev 12, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 4: Dev 15, If 1, Class=Video, Driver=uvcvideo, 480M
|__ Port 4: Dev 15, If 0, Class=Video, Driver=uvcvideo, 480M
|__ Port 2: Dev 13, If 0, Class=Video, Driver=uvcvideo, 480M
|__ Port 2: Dev 13, If 1, Class=Video, Driver=uvcvideo, 480M
|__ Port 3: Dev 14, If 0, Class=Video, Driver=uvcvideo, 480M
|__ Port 3: Dev 14, If 1, Class=Video, Driver=uvcvideo, 480M
|__ Port 4: Dev 11, If 1, Class=Human Interface Device, Driver=usbhid, 12M
|__ Port 4: Dev 11, If 0, Class=Human Interface Device, Driver=usbhid, 12M
|__ Port 8: Dev 3, If 1, Class=Video, Driver=uvcvideo, 480M
|__ Port 8: Dev 3, If 0, Class=Video, Driver=uvcvideo, 480M
|__ Port 9: Dev 4, If 0, Class=Vendor Specific Class, Driver=, 12M
bus001 Port 3.( Port 2, Port 3, Port 4)
kint@kint:/sys/bus/usb/devices/1-3/1-3.2$ cat /sys/bus/usb/devices/1-3/1-3.2/serial
HK100HA21P100043
3. lib库文件信息查看
3.1. 查看静态库属于哪种架构: x86 arm AArch64
$ readelf -h libceres.a
$ readelf -h libceres.a | grep Machine
>>> Machine: AArch64
$ readelf -h libceres.a | grep -e libceres.a -e Machine:
File: libceres.a(schur_eliminator_4_4_4.cc.o)
Machine: AArch64
$ ar -x libceres.a (解压静态库)
3.2. 查看动态库信息
file xxx
ldd xxx
$ file libceres.a
libceres.a: current ar archive
$ file libceres.so
libceres.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=ab60dba2cdc5175e1aa4f7442b8a3a19cf069a98, stripped
$ ldd libceres.so
linux-vdso.so.1 (0x0000007f8710c000)
libglog.so.0 => /usr/lib/aarch64-linux-gnu/libglog.so.0 (0x0000007f86e30000)
libspqr.so.2 => /usr/lib/aarch64-linux-gnu/libspqr.so.2 (0x0000007f86dfb000)
libcholmod.so.3 => /usr/lib/aarch64-linux-gnu/libcholmod.so.3 (0x0000007f86d3d000)
liblapack.so.3 => /usr/lib/aarch64-linux-gnu/liblapack.so.3 (0x0000007f8683a000)
libf77blas.so.3 => /usr/lib/aarch64-linux-gnu/libf77blas.so.3 (0x0000007f8680f000)
libcxsparse.so.3 => /usr/lib/aarch64-linux-gnu/libcxsparse.so.3 (0x0000007f867d6000)
libgomp.so.1 => /usr/lib/aarch64-linux-gnu/libgomp.so.1 (0x0000007f86799000)
libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000007f8676d000)
libstdc++.so.6 => /usr/lib/aarch64-linux-gnu/libstdc++.so.6 (0x0000007f865d9000)
libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000007f86520000)
libgcc_s.so.1 => /lib/aarch64-linux-gnu/libgcc_s.so.1 (0x0000007f864fc000)
libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000007f863a3000)
/lib/ld-linux-aarch64.so.1 (0x0000007f870e0000)
libgflags.so.2.2 => /usr/lib/aarch64-linux-gnu/libgflags.so.2.2 (0x0000007f86372000)
libsuitesparseconfig.so.5 => /usr/lib/aarch64-linux-gnu/libsuitesparseconfig.so.5 (0x0000007f8635e000)
libblas.so.3 => /usr/lib/aarch64-linux-gnu/libblas.so.3 (0x0000007f860ef000)
libamd.so.2 => /usr/lib/aarch64-linux-gnu/libamd.so.2 (0x0000007f860d7000)
libcolamd.so.2 => /usr/lib/aarch64-linux-gnu/libcolamd.so.2 (0x0000007f860c0000)
libccolamd.so.2 => /usr/lib/aarch64-linux-gnu/libccolamd.so.2 (0x0000007f860a7000)
libcamd.so.2 => /usr/lib/aarch64-linux-gnu/libcamd.so.2 (0x0000007f8608f000)
libmetis.so.5 => /usr/lib/aarch64-linux-gnu/libmetis.so.5 (0x0000007f86022000)
libgfortran.so.4 => /usr/lib/aarch64-linux-gnu/libgfortran.so.4 (0x0000007f85f1f000)
libatlas.so.3 => /usr/lib/aarch64-linux-gnu/libatlas.so.3 (0x0000007f85cde000)
3.3 arm环境找/usr/lib/x86_64-linux-gnu/libglog.so
make[2]: *** No rule to make target '/usr/lib/x86_64-linux-gnu/libglog.so', needed by 'xx_ws/devel/lib/liblasercamcal.so'. Stop.
重装glog 都没有解决问题, 对比之前的cmake文件,findpackage(glog)源码编译都是正常的, 现在只是多了ceres库,
怀疑是ceres静态库编译带入的。 重新源码编译并安装ceres库恢复正常
4. c++实现wifi连接
参考: xiaoqiang_qrcode_wifi_exec 通过二维码连接wifi功能
std::stringstream ss;
ss << "nmcli device wifi connect " << ssid << " password " << password;
std::string res = exec(ss.str().c_str());
if (res.find("successfully activated") != std::string::npos)
{
qrNotify.data = "连接wifi成功";
audioPub.publish(qrNotify);
ROS_INFO_STREAM("连接wifi成功");
auto ipList = ListIpAddresses();
if (ipList.size() != 0)
{
qrNotify.data = "当前机器人ip为 " + ipList[0] + "\n";
audioPub.publish(qrNotify);
ROS_INFO_STREAM("当前机器人ip为 " << ipList[0] << std::endl);
Sleep(5000);
}
}
else
{
qrNotify.data = "连接wifi失败";
ROS_INFO_STREAM("连接wifi失败");
audioPub.publish(qrNotify);
}
std::string exec(const char *cmd)
{
std::array<char, 128> buffer;
std::string result;
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
if (!pipe)
{
throw std::runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
{
result += buffer.data();
}
return result;
}
5. pcl kdtree_flann 出错 param_radius_
/usr/include/pcl-1.8/pcl/kdtree/kdtree_flann.h:233:29: error: field ‘param_radius_’ has incomplete type ‘flann::SearchParams’
::flann::SearchParams param_radius_;
sudo vim /usr/include/pcl-1.8/pcl/kdtree/kdtree_flann.h
修改:
::flann::SearchParams param_k_; 改为 ::flann::SearchParams *param_k_;
::flann::SearchParams param_radius_;改为 ::flann::SearchParams *param_radius_;
5. error while loading shared libraries: libg2o_core.so: cannot open shared object file
sudo vim /etc/ld.so.conf
添加路径:/usr/local/lib
sudo ldconfig
--------------------
或者
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
/etc/ld.so.conf 文件是一个系统级别的配置文件,用于指定动态链接器(ld.so)在运行时查找共享库文件的搜索路径。当程序在运行时需要加载共享库时,动态链接器使用该文件中列出的路径来搜索并加载相应的库文件。
每行路径都代表一个要搜索的目录,可以列出多个路径。路径可以是绝对路径,也可以是相对于当前文件系统根目录的相对路径。
当你需要安装新的共享库文件时,可以将该库文件所在的路径添加到 /etc/ld.so.conf 文件中。然后,使用 sudo ldconfig 命令来刷新动态链接器的缓存,以使其能够找到新添加的库文件。
ldconfig 命令是一个用于配置动态链接器的工具。它会读取 /etc/ld.so.conf 文件中列出的路径,并在运行时更新动态链接器的缓存,使其包含最新的库文件信息。这样,当程序需要加载共享库时,动态链接器就能够快速找到并加载所需的库文件。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib 这个命令是用来设置环境变量 LD_LIBRARY_PATH 的值。当程序在运行时需要加载共享库时,动态链接器会根据 LD_LIBRARY_PATH 的值来搜索共享库文件的路径。
具体来说,这个命令将当前的 LD_LIBRARY_PATH 值与 /usr/local/lib 目录拼接起来,并将结果重新赋值给 LD_LIBRARY_PATH。这样做的目的是将 /usr/local/lib 目录添加到动态链接器的搜索路径中。
与此相关,/etc/ld.so.conf 文件起到了类似的作用。它列出了动态链接器在运行时搜索共享库文件的路径。当系统启动时,动态链接器会读取 /etc/ld.so.conf 文件中列出的路径,并将这些路径作为默认的库文件搜索路径。然而,有时候我们可能希望指定额外的库文件路径,而不仅仅依赖于 /etc/ld.so.conf 中的路径。这时,可以使用 LD_LIBRARY_PATH 环境变量来设置附加的库文件路径。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib 这个命令就是将 /usr/local/lib 目录添加到 LD_LIBRARY_PATH 中。这样设置后, 动态链接器会在搜索共享库文件时先查找 LD_LIBRARY_PATH 中指定的路径,然后再查找 /etc/ld.so.conf 中的路径。
总结:
1 )/etc/ld.so.conf 文件用于指定动态链接器在运行时搜索共享库文件的路径。文件列出了动态链接器默认的库文件搜索路径。
2) sudo ldconfig 命令用于刷新动态链接器的缓存,以使其能够找到新添加的库文件。
3) 通过编辑 /etc/ld.so.conf 文件并运行 sudo ldconfig 命令,可以管理系统中的共享库文件路径。
4) export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib 命令用来设置 LD_LIBRARY_PATH 环境变量,将 /usr/local/lib 目录添加到动态链接器的库文件搜索路径中。
5) LD_LIBRARY_PATH 环境变量可以用来指定额外的库文件路径,优先级高于 /etc/ld.so.conf 中的路径。
6. 带密码执行sudo,免输密码执行
将密码以参数形式追加到脚本
echo [password] | sudo -S apt install libdw-dev
7. git配置支持中文和github走代\理
[user]
email = xxx@xxx.com.cn
name = xxx
[http]
postBuffer = 1048576000
sslVerify = true
# proxy = socks5://127.0.0.1:1080
[credential]
helper = cache --timeout=3600
#[init]
# defaultBranch = main
[core]
quotepath = false
#[https]
# proxy = socks5://127.0.0.1:1080
[http "https://github.com"]
proxy = socks5://127.0.0.1:1080
[https "https://github.com"]
proxy = socks5://127.0.0.1:1080
8. 禁用搜狗输入法Linux版的Ctrl+Shift+F的简繁切换快捷键
参考:https://blog.csdn.net/qq_42731705/article/details/124673934
解决方案
首先打开搜狗拼音的配置文件
gedit ~/.config/sogoupinyin/conf/env.ini
ShortCutFanJian=0
然后找到这行,将后面的值改为0,保存文件
完成这一步还没结束,还需要修改fcitx的配置文件,打开fcitx的相关配置文件
gedit ~/.config/fcitx/conf/fcitx-chttrans.config
#Hotkey=CTRL_SHIFT_F
Hotkey=CTRL_SHIFT_)
将前面的注释取消,随便修改一个不常用的快捷键,比如 Hotkey=CTRL_SHIFT_)
【c++】
1. Backward-cpp 定位问题track 小工具
github
[参考] (https://zhuanlan.zhihu.com/p/397148839)
- 安装第三方库:
sudo apt-get install libdw-dev
- 拷贝库文件
wget https://raw.githubusercontent.com/bombela/backward-cpp/master/backward.hpp
sudo mv backward.hpp /usr/include
3) CMakeLists中添加link
target_link_libraries(dw_test dw )
- demo cpp
#include<stdio.h>
#include<stdlib.h>
#define BACKWARD_HAS_DW 1
#include "backward.hpp"
namespace backward{
backward::SignalHandling sh;
}
int main(){
char *c = "hello world";
c[1] = 'H';
}
2. execlp c++中代码运行shell指令
int execlp(const char *file, const char *arg, ...);
"file" 是要执行的程序文件的名称,"arg" 是传递给新进程的参数。
#include <unistd.h>
#include <iostream>
int main() {
if (fork() == 0) {
execlp("ls", "ls", "-l", NULL);
} else {
std::cout << "Parent process" << std::endl;
}
return 0;
}
int main(int argc, char **argv)
{
ros::init(argc,argv,"sub_spec");
ros::NodeHandle n;
execlp("rostopic", "rostopic", "echo", "/IMU_data",NULL);
ros::spin();
}
cmake_minimum_required(VERSION 3.0)
project(ExeclpExample)
add_executable(ExeclpExample main.cpp)
3. std::stringstream
std::stringstream 是 C++ 中的一个类,提供了一个输入/输出流接口,用于将内存中的字符串缓冲区视为流进行读写操作。它可以用于从字符串中读取输入,或将输出写入到字符串中。
在提供的代码中,std::stringstream 被用来根据空格将存储在 topics_string 中的字符串分割为单个单词或标记。这是通过使用 >> 运算符实现的,该运算符从流中读取输入并返回流对象本身。
std::stringstream ss(topics_string);
std::string source;
while (ss >> source)
{
LOG(INFO)<<"source: "<<source;
}
4. glog
条件记录
我们可以使用LOG_IF()来到达有条件的输出日志的目的;
LOG_IF(INFO, i > 15) << "i > 15"; //当i > 15时,记录Log;
周期记录
通过LOG_EVERY_N()实现周期性的输出日志,意思解释说,LOG_EVERY_N()执行n次才输出一次Log;
LOG_EVERY_N(INFO, 3) << "i: " << i; //每隔3次输出一次信息;
条件加周期记录
通过LOG_IF_EVERY_N实现,当满足条件之后,每隔n次输出Log;
LOG_IF_EVERY_N(INFO, i > 10, 3) << "i > 10, i: " << i; //当i > 10之后,每隔3次输出一次信息;
限制Log输出次数
通过LOG_FIRST_N()实现,只输出前n次信息;
LOG_FIRST_N(INFO, 4) << "i: " << i; // 输出前4次Log
支持调试模式
调试模式的宏仅在调试模式下有效,在非调试模式编译时为空。
在宏前面加D就支持了调试模式;
DLOG(), DLOG_IF(), DLOG_EVERY_N(), …
5. cmake 找不到OMPL库
By not providing “FindOMPL.cmake” in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by “OMPL”, but
CMake did not find one.
whereis
whereis 命令在 Ubuntu 和其他 Linux 发行版中用于定位可执行文件的二进制、源文件和手册页。
whereis [选项] 程序名
常用选项
-b:只搜索二进制文件。
-m:只搜索手册页。
-s:只搜索源代码文件。
-u:搜索通常未知的、未分类的文件。
-B:更改二进制文件的搜索路径。
-M:更改手册页的搜索路径。
-S:更改源代码文件的搜索路径。
注意
whereis 命令有一些限制,例如它可能不会搜索用户自定义的路径,而且只会搜索在其数据库中已知的文件。如果你需要更详细的搜索,可以考虑使用 locate 或 find 命令。
注意
robot@robot:$ whereis ompl
ompl: /usr/include/ompl /usr/share/ompl
robot@robot:$ cd /usr/share/ompl/cmake
robot@robot:/usr/share/ompl/cmake$ ls
omplConfig.cmake omplConfigVersion.cmake
robot@robot:/usr/share/ompl/cmake$ sudo cp omplConfig.cmake OMPLConfig.cmake
robot@robot:/usr/share/ompl/cmake$ ls
omplConfig.cmake OMPLConfig.cmake omplConfigVersion.cmake
【cv】
1. opencv mat的构建
cv::Mat im_m(map->info.width, map->info.height, CV_8UC1, cv::Scalar(0));
Mat M(3, 3, CV_8UC3, Scalar(0, 0, 255)); //scale要和通道数目一致
cout << "M:" << endl << M << endl;
Mat a = (Mat_<float>(2,2)<<1,2,3,4);
float b[4]={5,6,7,8};
Mat c = Mat(2,2,CV_32F,b).clone();
memcpy(a.data,b,sizeof(float)*4);
memcpy(b,a.data,sizeof(float)*4);
opencv Mat与Vector、Mat与数组、Vector与数组之间互转 详解
cv::Mat im_m = cv::Mat(map->data).clone();//将vector变成单列的mat,这里需要clone(),因为这里的赋值操作是浅拷贝
cv::Mat dest = im_m.reshape(1, map->info.height);
uchar arr[4][3] = { { 1, 1,1 },{ 2, 2,2 },{ 3, 3,3 },{ 4,4, 4 } };
cv::Mat srcData(4, 3, CV_8UC1, arr);
Mat dest= (cv::Mat_<float>(2, 1) << 0.4404, 0.3111);
vector<uchar> array;
if (dest.isContinuous())
{
array.assign(dest.datastart, dest.dataend);//重新分配vector
}
uchar cbuf[height][width];
cv::Mat img(height, width, CV_8UC1, cbuf);
uchar **array = new uchar*[mat.rows];
for (int i=0; i<mat.rows; ++i)
array[i] = new uchar[mat.cols];
for (int i = 0; i < mat.rows; ++i)
array[i] = mat.ptr<uchar>(i);
uchar arr[] = { 1, 1,1 ,2 ,2 ,1 ,2 ,1 };
vector<uchar> vec(arr, arr + sizeof(arr) / sizeof(uchar));
uchar*buffer = new uchar[vec.size()];
if (!vec.empty())
{
memcpy(buffer, &vec[0], vec.size() * sizeof(uchar));
}
【docker】
1. gui环境: ubuntu 18.04 + melodic 环境下运行docker[ubuntu22.04 + humble]
docker 映射运行
docker run -it --net=host --privileged --env="DISPLAY" --env="QT_X11_NO_MITSHM=1" -e PYTHONBUFFERED=1 -v /etc/timezone:/etc/timezone:ro -v /etc/localtime:/etc/localtime:ro -v /home/xx/ros2/docker_humble_ws:/root/docker_humble_ws:rw -v /tmp/.X11-unix:/tmp/.X11-unix:rw -v $HOME/.Xauthority:/root/.Xauthority:ro --device=/dev/bus/usb:/dev/bus/usb 091a8ef51d0a /bin/bash
docker中输入gazebo,加载gui会出现问题
# 问题:No protocol specified
xhost +local:root
xhost 是一个用于管理 X 服务器访问控制列表(ACL)的实用程序。xhost 命令允许您添加或删除主机名或用户名称以允许或拒绝他们访问您的 X 服务器。X 服务器是基于 Unix 和 Linux 系统上的图形显示系统的关键组件。
xhost +local:root 命令允许本地 root 用户访问您的 X 服务器。这对于某些需要图形显示的应用程序(例如,通过 sudo 运行的图形应用程序)可能是必要的。
xhost +local:root 命令的详细解释:
xhost:调用 xhost 命令
+:表示允许访问
local:root:表示本地 root 用户
需要注意的是,允许 root 用户访问 X 服务器可能会导致安全风险。在完成需要 root 访问权限的操作后,建议禁止 root 用户访问 X 服务器,使用以下命令:
xhost -local:root
这将禁止本地 root 用户访问您的 X 服务器。
2 docker pull 加速
部署docker服务器编辑配置文件:/etc/docker/daemon.json
网易云 https://hub-mirror.c.163.com
百度云 https://mirror.baidubce.com
DaoCloud http://f1361db2.m.daocloud.io
阿里云 https://ustc-edu-cn.mirror.aliyuncs.com
Github https://ghcr.io
{
"registry-mirrors": [
"https://ustc-edu-cn.mirror.aliyuncs.com",
"https://mirror.baidubce.com"
]
}
3. docker 编译时换源apt安装加速
RUN sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list
RUN apt-get clean
RUN apt-get update
4. docker 编译时换源pip安装加速
RUN pip3 config set global.index-url http://mirrors.aliyun.com/pypi/simple
RUN pip3 config set install.trusted-host mirrors.aliyun.com
5. docker 给用户赋权限运行
sudo gpasswd -a username docker #将普通用户username加入到docker组中
newgrp docker #更新docker组
6. docker容器命令tab无法自动补全问题
1、安装 bash-complete
apt-get install -y bash-completion
2、确认shell的解释器是否是bash,需把shell的解释器更改为bash
执行以下命令,若得到结果/bin/sh -> dash,则说明shell的解释器为dash
ls -l /bin/sh
执行以下命令,然后选择no
dpkg-reconfigure dash
3、运行bash_completion 使之生效
cd /usr/share/bash-completion
chmod +x bash_completion
./bash_completion
ref:https://blog.csdn.net/Mr_chunping/article/details/122089360
【shell】
if [[ ]] []操作
注意表达式与符号间的空格: [[ 表达式 ]] [ 表达式 ]
在Ubuntu的shell中,if语句用于执行条件判断。有三种常见的条件判断语法可以在if语句中使用:[],[[ ]]和[ -e]。
[]:这是最基本的条件判断语法。在[]内部,可以使用各种条件运算符来比较字符串、数字或文件。例如,使用-eq运算符比较两个数字是否相等,使用==运算符比较两个字符串是否相等。[]语法不支持模式匹配,只能进行简单的比较。
[[ ]]:这是比较强大的条件判断语法。与[]不同,[[ ]]支持更多的条件运算符和模式匹配。在[[ ]]内部,可以使用运算符==、!=、<、>、<=、>=来比较字符串,还可以使用=~来进行模式匹配。[[ ]]还支持逻辑运算符&&和||来组合多个条件。
[ -e]:这是用于检查文件是否存在的条件判断语法。[ -e 文件路径 ]用于检查指定路径的文件是否存在。如果文件存在,则条件为真,否则条件为假。这在脚本中经常用于检查文件是否存在并根据结果执行不同的操作。
if [["${chassis_type}" == "a" || "${chassis_type}" == "b"]]
then
if [ -e /home/firefly/.ros/a.yaml ]; then
echo "Has up_depth_cam_cal.yaml keep"| tee -a ${log_file}
else
echo "No /home/firefly/.ros/a.yaml, replace !!!"
cp ${depth_calib_path}/${chassis_type}_up.yaml /home/firefly/.ros/a.yaml
fi;
else
echo "No process "| tee -a ${log_file}
fi
echo "<<<<===finish " | tee -a ${log_file}
函数表达式的执行不带括号
function getChassisInfo()
{
echo "===>getChassisInfo" | tee -a ${log_file}
echo "chassis_type : ${chassis_type}"
echo "lidar_type : ${lidar_type}"
}
getChassisInfo
【python】
ubuntu20.04 /usr/bin/env: ‘python’: No such file or directory
~# whereis python3
python3: /usr/bin/python3 /usr/bin/python3.8 /usr/bin/python3.8-config /usr/lib/python3 /usr/lib/python3.8 /usr/lib/python3.9 /etc/python3 /etc/python3.8 /usr/local/lib/python3.8 /usr/include/python3.8 /usr/share/python3 /usr/share/man/man1/python3.1.gz
~# sudo ln -s /usr/bin/python3 /usr/bin/python