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指定单独编译与恢复整体编译
- 【ROS2】
- 【apt]】
- 【git】
- 【ubuntu】
- 【c++】
- 【cv】
- 【docker】
【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
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失败的解决方法
第三种本地化离线方式处理:
1. clone rosdistro 到本地
mkdir -p ~/.ros/rosdep
cd ~/.ros/rosdep
git clone https://github.com/ros/rosdistro
2. 修改 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
3. 修改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'
4. 修改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'
5. . 修改_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'
6. 重新更新
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
-----------------
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=""
【ROS2】
rosidl_cmake/cmake/rosidl_generate_interfaces.cmake:240 (list)
工作空间路径有中文
【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 中的路径。
【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(), …
【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 服务器。