鱼香ROS官网:https://fishros.com/ (鱼神!)
生成 install 文件:catkin_make install
功能包命名:要小写开头,不然会报警告⚠
ROS + Vscode 配置:http://t.csdnimg.cn/X34DS
中转节点在ROS中的使用
创建工作空间&功能包 理论上工作空间在任何文件夹中可以建立,为了保证组织性和环境配置的简化,一般都位于主目录下建立:
1 2 3 4 5 6 7 8 9 10 11 mkdir workspace #名字可以随意 cd workspace #进入文件夹 mkdir src cd src catkin_init_workspace cd .. catkin_make cd src catkin_create_pkg Test_pkg roscpp rospy std_msgs cd .. catkin_make
环境变量 单次添加 1 2 cd workspace source ./devel/setup.bash
多次添加 1 2 3 vi|gedit ~/.bashrc #最后一行添加 source ~/workspace/devel/setup.bash
消息类型 sensor_msgs::Imu can_msgs/Frame ROS—CAN 通信思考 注意:在ROS中,接受CAN报文是一种主动的行为,需要不断定期的读取;
思考:实时性 不断读取造成的开销
解决方案:
可以使用低延迟的通讯协议CAN FD
编写一种能够实现中断的功能 (ing)
多线程处理: 如下(可扩展思路)
ROS 相关写法 ROS 多线程 消息回调函数:
ros::spin() ros::spinOnce()
1 2 3 4 5 6 7 8 /** * The MultiThreadedSpinner object allows you to specify a number of threads to use * to call callbacks. If no explicit # is specified, it will use the # of hardware * threads available on your system. Here we explicitly specify 4 threads. */ ros::MultiThreadedSpinner s(4); ros::spin(s);
sync(同步) 官方demo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include <message_filters/subscriber.h> #include <message_filters/time_synchronizer.h> #include <sensor_msgs/Image.h> #include <sensor_msgs/CameraInfo.h> using namespace sensor_msgs; using namespace message_filters; void callback(const ImageConstPtr& image, const CameraInfoConstPtr& cam_info) { // Solve all of perception here... } int main(int argc, char** argv) { ros::init(argc, argv, "vision_node"); ros::NodeHandle nh; message_filters::Subscriber<Image> image_sub(nh, "image", 1); message_filters::Subscriber<CameraInfo> info_sub(nh, "camera_info", 1); TimeSynchronizer<Image, CameraInfo> sync(image_sub, info_sub, 10); sync.registerCallback(boost::bind(&callback, _1, _2)); ros::spin(); return 0; }
Async(异步) 异步线程处理,同时拥有start() 和stop() 函数,并且在销毁的时候会自动停止。
1 2 ros::AsyncSpinner s(4); s.start();
callback 写法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class Listener { public: ros::NodeHandle node_handle_; ros::V_Subscriber subs_; Listener(const ros::NodeHandle& node_handle): node_handle_(node_handle) { } void init() { subs_.push_back(node_handle_.subscribe<std_msgs::String>("chatter", 1000, boost::bind(&Listener::chatterCallback, this, _1, "User 1"))); subs_.push_back(node_handle_.subscribe<std_msgs::String>("chatter", 1000, boost::bind(&Listener::chatterCallback, this, _1, "User 2"))); subs_.push_back(node_handle_.subscribe<std_msgs::String>("chatter", 1000, boost::bind(&Listener::chatterCallback, this, _1, "User 3"))); } void chatterCallback(const std_msgs::String::ConstPtr& msg, std::string user_string) { ROS_INFO("I heard: [%s] with user string [%s]", msg->data.c_str(), user_string.c_str()); } }; int main(int argc, char **argv) { ros::init(argc, argv, "listener_with_userdata"); ros::NodeHandle n; Listener l(n); l.init(); ros::spin(); return 0; }
定时器 1 ros::Timer timer = x.createTimer(ros::Duration(时间),callback);
JsonCpp库 安装依赖库:
1 2 3 sudo apt-get install ros-<distro>-jsoncpp ~~~S 示例:
#include <jsoncpp/json/json.h>
Json::CharReaderBuilder readerBuilder;
Json::Value root;
std::string errs;
std::string jsonString = msg->data.c_str();
std::istringstream ss(jsonString);
if (Json::parseFromStream(readerBuilder, ss, &root, &errs))
{
// 提取字段
std::string imei = root["imei"].asString();
std::string msgId = root["msgId"].asString();
std::string controlType = root["controlType"].asString();
}
ros开机自启动 以下两种方案都基于bash脚本文件,首先我们先生成编写脚本文件:
1 2 3 sudo nano ros_start.sh sudo vi ros_start.sh
编写脚本内容(例):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #!/bin/bash #author Tree #description:TEST sleep 5s #此处要多做等待,等待系统接口都正常运行 PASSWORD="*****" echo "$PASSWORD" | sudo -S chmod 777 /dev/ttyUSB0 # 启动 roscore source /opt/ros/noetic/setup.bash roscore & # 使用后台运行 # 等待 roscore 启动 sleep 5s # 初始等待,给 roscore 启动一些时间 # 启动节点 source /home/tree/robospace/devel/setup.bash rosrun my_minimal_nodes my_minimal_nodes_node & rostopic echo /imu # 直接在当前终端输出
添加权限:
1 sudo chmod 777 -R ros_start.sh
补:命令行式输出示范
1 gnome-terminal --tab --title="roscore" -- bash -c "source /opt/ros/noetic/setup.bash;roscore; exec bash"
方案一:使用ubuntu自带程序管理器 此方案适用于带有图形桌面的linux系统,较为简单
先检查对应的软件包是否存在,一般都是自带的,没有可通过该指令下载
1 sudo apt-get install gnome-startup-applications
打开管理器:
1 gnome-session-properties
参考如下设置: 添加后即可完成自启动设置
方案二:使用 systemd 创建服务 使用linux自带的systemd服务管理器 此方案适用于没有图形显示的linux系统
在/etc/systemd/system新建service文件:
1 2 3 sudo nano my_ros_service.servoce sudo vi my_ros_service.service
编写内容:
1 2 3 4 5 6 [Unit] After=network.service [Service] ExecStart=/home/tree/ros_start.sh [Install] WantedBy=default.target
在etc/systemd/system路径下使用命令,添加权限:
1 2 3 sudo chmod +x my_ros_service.service sudo chmod 777 my_ros_service.service
将service文件设置为开机启动:
1 sudo systemctl enable my_ros_service.service
查看service文件启动状态:
1 sudo systemctl status my_ros_service.service
手动启动service文件,用于测试
1 sudo systemctl start my_ros_service.service
以上完成使用systemd服务管理器的自启动方式