头文件
#include <ros/ros.h>
#include <nav_msgs/Odometry.h>
#include <sensor_msgs/Imu.h>
#include <sensor_msgs/NavSatFix.h>
#include <sensor_msgs/PointCloud2.h>
#include <std_msgs/Float32.h>
#include <cv_bridge/cv_bridge.h>
类定义
class Scheduler {
public:
Scheduler(ros::NodeHandle& node_handle);
~Scheduler();
void initialize();
void run();
private:
void imuHandler(const sensor_msgs::Imu::ConstPtr& msg);
void gpsHandler(const sensor_msgs::NavSatFix::ConstPtr& msg);
void cloudHandler(const sensor_msgs::PointCloud2ConstPtr& msg);
void imageHandler(const sensor_msgs::Image::ConstPtr& msg);
void compressedImageHandler(const sensor_msgs::CompressedImage::ConstPtr& msg);
private:
ros::NodeHandle node_handle_;
// Subscriber
ros::Subscriber imu_sub_;
ros::Subscriber gnss_sub_;
ros::Subscriber cloud_sub_;
ros::Subscriber image_sub_;
ros::Subscriber compressed_image_sub_;
// Publisher
ros::Publisher location_pub_;
};
初始化
void Scheduler::initialize() {
imu_sub_ = node_handle_.subscribe("imu_topic", 10, &Scheduler::imuHandler, this, ros::TransportHints().tcpNoDelay());
gnss_sub_ = node_handle_.subscribe("gps_topic", 2, &Scheduler::gpsHandler, this);
cloud_sub_ = node_handle_.subscribe<sensor_msgs::PointCloud2>("lidar_topic", 1, &Scheduler::cloudHandler, this);
image_sub_ = node_handle_.subscribe("camera_topic", 5, &Scheduler::imageHandler, this);
compressed_image_sub_ = node_handle_.subscribe("camera_topic", 5, &Scheduler::compressedImageHandler, this);
}
回调函数
void Scheduler::imuHandler(const sensor_msgs::Imu::ConstPtr& msg) {
time = msg->header.stamp.toSec();
// acceleration
Eigen::Vector3d acceleration(msg->linear_acceleration.x,
msg->linear_acceleration.y,
msg->linear_acceleration.z);
// angular velocity
Eigen::Vector3d angular_velocity(msg->angular_velocity.x,
msg->angular_velocity.y,
msg->angular_velocity.z);
}
void Scheduler::gpsHandler(const sensor_msgs::NavSatFix::ConstPtr& msg) {
Eigen::Vector3d position(msg->longitude, msg->latitude, msg->altitude);
}
void Scheduler::cloudHandler(const sensor_msgs::PointCloud2ConstPtr& msg) {
pcl::PointCloud<pcl::PointXYZI>::Ptr cloud;
pcl::fromROSMsg(*msg, *cloud);
}
void Scheduler::imageHandler(const sensor_msgs::ImageConstPtr &msg) {
double time_nsecond = msg->header.stamp.toNSec();
cv::Mat color_image;
cv_bridge::CvImageConstPtr srcImage = cv_bridge::toCvShare(msg, sensor_msgs::image_encodings::RGB8);
}
服务器
bool add(beginner_tutorials::AddTwoInts::Request &req,
beginner_tutorials::AddTwoInts::Response &res)
{
res.sum = req.a + req.b;
ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
ROS_INFO("sending back response: [%ld]", (long int)res.sum);
return true;
}
ros::ServiceServer service = n.advertiseService("add_two_ints", add);
客户端
ros::NodeHandle n;
ros::ServiceClient client = n.serviceClient<beginner_tutorials::AddTwoInts("add_two_ints");
beginner_tutorials::AddTwoInts srv;
srv.request.a = atoll(argv[1]);
srv.request.b = atoll(argv[2]);
if (client.call(srv)) {
ROS_INFO("Sum: %ld", (long int)srv.response.sum);
} else {
ROS_ERROR("Failed to call service add_two_ints");
return 1;
}
参数服务器
std::string parameter;
node_handle_.param<std::string>("param", parameter, "parameters.xml");
主函数
int main(int argc, char **argv) {
ros::init(argc, argv, "node");
ros::NodeHandle node_handle("~");
ros::console::set_logger_level(ROSCONSOLE_DEFAULT_NAME, ros::console::levels::Info);
double time = ros::Time::now().toSec() // 获取系统时间
Scheduler scheduler(node_handle);
scheduler.initialize();
scheduler.run();
return 0;
}
常用命令
按时间截取
rosbag filter orign.bag new.bag "t.secs >=576210103 and t.secs <=576210303"
显示数据包的信息
rosbag info data.bag
播放数据包
rosbag play data.bag
可视化
rqt_image_view
录包
rosbag record命令是用于在ros系统中录取系统中其他ros节点发出来的topic的message。录取的的包可以使用rosbag play命令来回放,订阅这些消息的node节点就可以收到这些消息,进而执行对应的程序。这样的话,就可以将自动驾驶汽车或者无人机、机器人等自动化机器在室外一些环境下遇到的问题,通过录包的方法拿到办公室来仔细研究解决。
rosbag record命令在终端下显示完整命令参数如下:
kitty@kitty-TM1705:~$ rosbag record -help
Usage: rosbag record TOPIC1 [TOPIC2 TOPIC3 ...]
Record a bag file with the contents of specified topics.
Options:
-h, --help show this help message and exit
-a, --all record all topics
-e, --regex match topics using regular expressions
-x EXCLUDE_REGEX, --exclude=EXCLUDE_REGEX
exclude topics matching the follow regular expression
(subtracts from -a or regex)
-q, --quiet suppress console output
-o PREFIX, --output-prefix=PREFIX
prepend PREFIX to beginning of bag name (name will
always end with date stamp)
-O NAME, --output-name=NAME
record to bag with name NAME.bag
--split split the bag when maximum size or duration is reached
--max-splits=MAX_SPLITS
Keep a maximum of N bag files, when reaching the
maximum erase the oldest one to keep a constant number
of files.
--size=SIZE record a bag of maximum size SIZE MB. (Default:
infinite)
--duration=DURATION record a bag of maximum duration DURATION in seconds,
unless 'm', or 'h' is appended.
-b SIZE, --buffsize=SIZE
use an internal buffer of SIZE MB (Default: 256, 0 =
infinite)
--chunksize=SIZE Advanced. Record to chunks of SIZE KB (Default: 768)
-l NUM, --limit=NUM only record NUM messages on each topic
--node=NODE record all topics subscribed to by a specific node
-j, --bz2 use BZ2 compression
--lz4 use LZ4 compression
--tcpnodelay Use the TCP_NODELAY transport hint when subscribing to
topics.
--udp Use the UDP transport hint when subscribing to topics.
rosbag record TOPIC1 [TOPIC2 TOPIC3 ...] 这是最简单的使用方法是。比如录取message_1的命令:rosbag record message_1;
通常的使用都是根据需求和可选的参数配合使用的,比如要录所有的topic,使用rosbag record -a命令。
查看消息
rostopic echo [topic name]
当echo topic: /radar_all_tracker时,如果只想接收 header,使用方式如下,
ros2 topic echo /radar_all_tracker | grep header -A4
-A4表示接收 header 后四行
参考文献
https://blog.csdn.net/moyu123456789/article/details/97283335https://blog.csdn.net/xiaocainiaoshangxiao/article/details/13742123https://blog.csdn.net/jack_20/article/details/71249170https://blog.csdn.net/qq_28087491/article/details/113367676