1+ #include " infinite_sense.h"
2+ #include " video_cam.h"
3+ #include < unordered_map>
4+ #include < ros/ros.h>
5+ #include < cv_bridge/cv_bridge.h>
6+ #include < image_transport/image_transport.h>
7+ #include < sensor_msgs/Imu.h>
8+
9+
10+ struct video_config {
11+ bool onboard_imu = true ;// 使用内部IMU
12+ bool extern_imu = false ;// 使用外部IMU,TODO
13+ std::string imu_name = " onboard_imu" ;
14+
15+ // 相机名称 + 设备ID
16+ std::pair<std::string, int > CAM3_Video = {" left_cam" , -1 };
17+ std::pair<std::string, int > CAM4_Video = {" right_cam" , -1 };
18+ std::pair<std::string, int > CAM1_Video = {" front_cam" , -1 };
19+ std::pair<std::string, int > CAM2_Video = {" rear_cam" , -1 }; // -1 代表没有
20+
21+ // 通信方式
22+ int type = 0 ; // 0 --> 串口通信 1 --> 网口通信
23+ std::string uart_dev = " /dev/ttyACM0" ;
24+ std::string net_ip = " 192.168.1.188" ;
25+ int net_port = 8888 ;
26+ };
27+ video_config cfg;
28+
29+ using namespace infinite_sense ;
30+
31+ inline ros::Time CreateRosTimestamp (const uint64_t mico_sec) {
32+ uint32_t nsec_per_second = 1e9 ;
33+ auto u64 = mico_sec * 1000 ;
34+ uint32_t sec = u64 / nsec_per_second;
35+ uint32_t nsec = u64 - (sec * nsec_per_second);
36+ return {sec, nsec};
37+ }
38+
39+ class CamDriver {
40+ public:
41+ CamDriver (ros::NodeHandle &nh) : node_(nh), it_(node_) {}
42+ void ImuCallback (const void *msg, size_t ) {
43+ const auto *imu_data = static_cast <const ImuData *>(msg);
44+ sensor_msgs::Imu imu_msg_data;
45+ imu_msg_data.header .frame_id = " map" ;
46+ imu_msg_data.header .stamp = CreateRosTimestamp (imu_data->time_stamp_us );
47+
48+ imu_msg_data.angular_velocity .x = imu_data->g [0 ];
49+ imu_msg_data.angular_velocity .y = imu_data->g [1 ];
50+ imu_msg_data.angular_velocity .z = imu_data->g [2 ];
51+
52+ imu_msg_data.linear_acceleration .x = imu_data->a [0 ];
53+ imu_msg_data.linear_acceleration .y = imu_data->a [1 ];
54+ imu_msg_data.linear_acceleration .z = imu_data->a [2 ];
55+
56+ imu_msg_data.orientation .w = imu_data->q [0 ];
57+ imu_msg_data.orientation .x = imu_data->q [1 ];
58+ imu_msg_data.orientation .y = imu_data->q [2 ];
59+ imu_msg_data.orientation .z = imu_data->q [3 ];
60+ imu_pub_.publish (imu_msg_data);
61+ }
62+
63+ // 自定义回调函数
64+ void ImageCallback (const void *msg, size_t ) {
65+ const auto *cam_data = static_cast <const CamData *>(msg);
66+ const cv::Mat image_mat (cam_data->image .rows , cam_data->image .cols , CV_8UC1, cam_data->image .data );
67+ sensor_msgs::ImagePtr image_msg =
68+ // mono8:灰度类型,bgr8:彩图,具体需要根据相机类型进行修改
69+ cv_bridge::CvImage (std_msgs::Header (), " bgr8" , image_mat).toImageMsg ();
70+ image_msg->header .stamp = CreateRosTimestamp (cam_data->time_stamp_us );
71+ image_pubs_[cam_data->name ].publish (image_msg);
72+ }
73+
74+ void Init () {
75+
76+ if (cfg.type == 0 ) {
77+ synchronizer_.SetUsbLink (cfg.uart_dev , 921600 );
78+ } else if (cfg.type == 1 ) {
79+ synchronizer_.SetNetLink (cfg.net_ip , cfg.net_port );
80+ }
81+
82+ std::vector<std::pair<std::string, int >> cam_list;
83+ if (cfg.CAM1_Video .second >= 0 ) cam_list.push_back (cfg.CAM1_Video );
84+ if (cfg.CAM2_Video .second >= 0 ) cam_list.push_back (cfg.CAM2_Video );
85+ if (cfg.CAM3_Video .second >= 0 ) cam_list.push_back (cfg.CAM3_Video );
86+ if (cfg.CAM4_Video .second >= 0 ) cam_list.push_back (cfg.CAM4_Video );
87+
88+ video_cam_ = std::make_shared<VideoCam>(cam_list);
89+ synchronizer_.UseSensor (video_cam_);
90+
91+
92+ if (cfg.onboard_imu ) {
93+ imu_pub_ = node_.advertise <sensor_msgs::Imu>(cfg.imu_name , 1000 );
94+ }
95+
96+ if (cfg.CAM1_Video .second >= 0 ) image_pubs_[cfg.CAM1_Video .first ] = it_.advertise (cfg.CAM1_Video .first , 30 );
97+ if (cfg.CAM2_Video .second >= 0 ) image_pubs_[cfg.CAM2_Video .first ] = it_.advertise (cfg.CAM2_Video .first , 30 );
98+ if (cfg.CAM3_Video .second >= 0 ) image_pubs_[cfg.CAM3_Video .first ] = it_.advertise (cfg.CAM3_Video .first , 30 );
99+ if (cfg.CAM4_Video .second >= 0 ) image_pubs_[cfg.CAM4_Video .first ] = it_.advertise (cfg.CAM4_Video .first , 30 );
100+
101+
102+ // 设置触发参数(如果有的话)
103+ // 这里用相机名作为 key
104+ if (cfg.CAM1_Video .second >= 0 ) video_cam_->SetParams ({{cfg.CAM1_Video .first , CAM_1}});
105+ if (cfg.CAM2_Video .second >= 0 ) video_cam_->SetParams ({{cfg.CAM2_Video .first , CAM_2}});
106+ if (cfg.CAM3_Video .second >= 0 ) video_cam_->SetParams ({{cfg.CAM3_Video .first , CAM_3}});
107+ if (cfg.CAM4_Video .second >= 0 ) video_cam_->SetParams ({{cfg.CAM4_Video .first , CAM_4}});
108+
109+
110+ synchronizer_.Start ();
111+ std::this_thread::sleep_for (std::chrono::milliseconds (5000 ));
112+
113+
114+ Messenger::GetInstance ().SubStruct (
115+ cfg.imu_name , std::bind (&CamDriver::ImuCallback, this , std::placeholders::_1, std::placeholders::_2));
116+
117+
118+ if (cfg.CAM1_Video .second >= 0 ) Messenger::GetInstance ().SubStruct (cfg.CAM1_Video .first , std::bind (&CamDriver::ImageCallback, this , std::placeholders::_1, std::placeholders::_2));
119+ if (cfg.CAM2_Video .second >= 0 ) Messenger::GetInstance ().SubStruct (cfg.CAM1_Video .first , std::bind (&CamDriver::ImageCallback, this , std::placeholders::_1, std::placeholders::_2));
120+ if (cfg.CAM3_Video .second >= 0 ) Messenger::GetInstance ().SubStruct (cfg.CAM1_Video .first , std::bind (&CamDriver::ImageCallback, this , std::placeholders::_1, std::placeholders::_2));
121+ if (cfg.CAM4_Video .second >= 0 ) Messenger::GetInstance ().SubStruct (cfg.CAM1_Video .first , std::bind (&CamDriver::ImageCallback, this , std::placeholders::_1, std::placeholders::_2));
122+ }
123+
124+ void Run () {
125+ ros::Rate loop_rate (1000 );
126+ while (ros::ok ()) {
127+ ros::spinOnce ();
128+ loop_rate.sleep ();
129+ }
130+ synchronizer_.Stop ();
131+ }
132+
133+ private:
134+ ros::NodeHandle &node_;
135+ ros::Publisher imu_pub_;
136+ image_transport::ImageTransport it_;
137+ std::unordered_map<std::string, image_transport::Publisher> image_pubs_;
138+ std::shared_ptr<VideoCam> video_cam_;
139+ Synchronizer synchronizer_;
140+ };
141+
142+ int main (int argc, char **argv) {
143+ ros::init (argc, argv, " ros_video_demo" , ros::init_options::NoSigintHandler);
144+ ros::NodeHandle node;
145+ CamDriver demo_node (node);
146+ demo_node.Init ();
147+ demo_node.Run ();
148+
149+ return 0 ;
150+ }
0 commit comments