00001
00002
00003
00004
00005
00006
00007
00008 #include <ibeo_lux/ibeo_lux_ros_msg_handler.h>
00009 #include <network_interface/network_interface.h>
00010 #include <network_interface/network_utils.h>
00011
00012
00013 #include <network_interface/TCPFrame.h>
00014
00015 #include <unordered_map>
00016 #include <vector>
00017 #include <queue>
00018 #include <deque>
00019 #include <string>
00020
00021 using std::string;
00022 using std::vector;
00023 using namespace AS::Network;
00024 using namespace AS::Drivers::IbeoLux;
00025
00026 TCPInterface tcp_interface;
00027 IbeoLuxRosMsgHandler handler;
00028 std::unordered_map<int64_t, ros::Publisher> pub_list;
00029
00030
00031 int main(int argc, char **argv)
00032 {
00033
00034 string ip_address = "192.168.0.1";
00035 int port = 12002;
00036 string frame_id = "ibeo_lux";
00037 bool is_fusion = false;
00038 int buf_size = AS::Drivers::Ibeo::IBEO_PAYLOAD_SIZE;
00039 std::deque<uint8_t> grand_buffer;
00040 std::queue<std::vector<uint8_t>> messages;
00041
00042
00043 ros::init(argc, argv, "ibeo_lux");
00044 ros::NodeHandle n;
00045 ros::NodeHandle priv("~");
00046 bool exit = false;
00047
00048 if (priv.getParam("ip_address", ip_address))
00049 {
00050 ROS_INFO("Ibeo LUX - Got ip_address: %s", ip_address.c_str());
00051
00052 if (ip_address == "")
00053 {
00054 ROS_ERROR("Ibeo LUX - IP Address Invalid");
00055 exit = true;
00056 }
00057 }
00058
00059 if (priv.getParam("port", port))
00060 {
00061 ROS_INFO("Ibeo LUX - Got port: %d", port);
00062
00063 if (port < 0)
00064 {
00065 ROS_ERROR("Ibeo LUX - Port Invalid");
00066 exit = true;
00067 }
00068 }
00069
00070 if (priv.getParam("is_fusion", is_fusion))
00071 {
00072 ROS_INFO("Ibeo LUX - Is Fusion ECU: %s", (is_fusion) ? "true" : "false");
00073 }
00074
00075 if (priv.getParam("sensor_frame_id", frame_id))
00076 {
00077 ROS_INFO("Ibeo LUX - Got sensor frame ID: %s", frame_id.c_str());
00078 }
00079
00080 if (exit)
00081 return 0;
00082
00083
00084 ros::Publisher raw_tcp_pub = n.advertise<network_interface::TCPFrame>("tcp_tx", 1);
00085 ros::Publisher pointcloud_pub = n.advertise<pcl::PointCloud <pcl::PointXYZ> >("as_tx/point_cloud", 1);
00086 ros::Publisher object_markers_pub = n.advertise<visualization_msgs::MarkerArray>("as_tx/objects", 1);
00087 ros::Publisher object_contour_points_pub = n.advertise<visualization_msgs::Marker>("as_tx/object_contour_points", 1);
00088
00089 ros::Publisher scan_data_pub, object_data_pub, vehicle_state_pub, error_warn_pub;
00090 ros::Publisher fusion_scan_2204_pub,
00091 fusion_scan_2205_pub,
00092 fusion_object_2225_pub,
00093 fusion_object_2280_pub,
00094 fusion_img_2403_pub,
00095 fusion_vehicle_2806_pub,
00096 fusion_vehicle_2807_pub;
00097
00098
00099 if (!is_fusion)
00100 {
00101 scan_data_pub = n.advertise<ibeo_msgs::ScanData2202>("parsed_tx/scan_data_2202", 1);
00102 object_data_pub = n.advertise<ibeo_msgs::ObjectData2221>("parsed_tx/object_data_2221", 1);
00103 vehicle_state_pub = n.advertise<ibeo_msgs::HostVehicleState2805>("parsed_tx/host_vehicle_state_2805", 1);
00104 error_warn_pub = n.advertise<ibeo_msgs::ErrorWarning>("parsed_tx/error_warning", 1);
00105
00106 pub_list.insert(std::make_pair(ErrorWarning::DATA_TYPE, error_warn_pub));
00107 pub_list.insert(std::make_pair(ScanData2202::DATA_TYPE, scan_data_pub));
00108 pub_list.insert(std::make_pair(ObjectData2221::DATA_TYPE, object_data_pub));
00109 pub_list.insert(std::make_pair(HostVehicleState2805::DATA_TYPE, vehicle_state_pub));
00110 }
00111 else
00112 {
00113 fusion_scan_2204_pub = n.advertise<ibeo_msgs::ScanData2204>("parsed_tx/scan_data_2204", 1);
00114 fusion_scan_2205_pub = n.advertise<ibeo_msgs::ScanData2205>("parsed_tx/scan_data_2205", 1);
00115 fusion_object_2225_pub = n.advertise<ibeo_msgs::ObjectData2225>("parsed_tx/object_data_2225", 1);
00116 fusion_object_2280_pub = n.advertise<ibeo_msgs::ObjectData2280>("parsed_tx/object_data_2280", 1);
00117 fusion_img_2403_pub = n.advertise<ibeo_msgs::CameraImage>("parsed_tx/camera_image", 1);
00118 fusion_vehicle_2806_pub = n.advertise<ibeo_msgs::HostVehicleState2806>("parsed_tx/host_vehicle_state_2806", 1);
00119 fusion_vehicle_2807_pub = n.advertise<ibeo_msgs::HostVehicleState2807>("parsed_tx/host_vehicle_state_2807", 1);
00120
00121 pub_list.insert(std::make_pair(ScanData2204::DATA_TYPE, fusion_scan_2204_pub));
00122 pub_list.insert(std::make_pair(ScanData2205::DATA_TYPE, fusion_scan_2205_pub));
00123 pub_list.insert(std::make_pair(ObjectData2225::DATA_TYPE, fusion_object_2225_pub));
00124 pub_list.insert(std::make_pair(ObjectData2280::DATA_TYPE, fusion_object_2280_pub));
00125 pub_list.insert(std::make_pair(CameraImage::DATA_TYPE, fusion_img_2403_pub));
00126 pub_list.insert(std::make_pair(HostVehicleState2806::DATA_TYPE, fusion_vehicle_2806_pub));
00127 pub_list.insert(std::make_pair(HostVehicleState2807::DATA_TYPE, fusion_vehicle_2807_pub));
00128 }
00129
00130
00131 ros::Time::waitForValid();
00132
00133 network_interface::TCPFrame tcp_raw_msg;
00134
00135 ReturnStatuses status;
00136
00137 ros::Rate loop_rate = (is_fusion) ? ros::Rate(1100) : ros::Rate(40);
00138
00139
00140 bool fusion_filter_sent = false;
00141
00142 while (ros::ok())
00143 {
00144 if (!tcp_interface.is_open())
00145 {
00146 if (is_fusion)
00147 fusion_filter_sent = false;
00148
00149 status = tcp_interface.open(ip_address.c_str(), port);
00150
00151 if (status != ReturnStatuses::OK)
00152 ROS_WARN("Ibeo LUX - Unable to connect to sensor at %s: %d - %s",
00153 ip_address.c_str(),
00154 static_cast<int>(status), return_status_desc(status).c_str());
00155
00156 ros::Duration(1.0).sleep();
00157 }
00158 else
00159 {
00160 if (is_fusion && !fusion_filter_sent)
00161 {
00162 std::vector<uint8_t> set_filter_cmd =
00163 {0xaf, 0xfe, 0xc0, 0xc2,
00164 0x00, 0x00, 0x00, 0x00,
00165 0x00, 0x00, 0x00, 0x08,
00166 0x00, 0x00, 0x20, 0x10,
00167 0x00, 0x00, 0x00, 0x00,
00168 0x00, 0x00, 0x00, 0x00,
00169 0x00, 0x05, 0x00, 0x02,
00170 0x00, 0x00, 0xff, 0xff};
00171
00172 ROS_INFO_THROTTLE(3, "Ibeo LUX - Sending Fusion filter command to begin transmission.");
00173
00174 status = tcp_interface.write(set_filter_cmd);
00175
00176 if (status != ReturnStatuses::OK)
00177 ROS_ERROR_THROTTLE(3, "Ibeo LUX - Failed to send Fusion filter command.");
00178 else
00179 fusion_filter_sent = true;
00180
00181 ros::Duration(0.5).sleep();
00182 }
00183 else
00184 {
00185 buf_size = IBEO_PAYLOAD_SIZE;
00186 std::vector<uint8_t> msg_buf;
00187 msg_buf.reserve(buf_size);
00188
00189 status = tcp_interface.read(&msg_buf);
00190
00191 if (status != ReturnStatuses::OK && status != ReturnStatuses::NO_MESSAGES_RECEIVED)
00192 {
00193 ROS_WARN("Ibeo ScaLa - Failed to read from socket: %d - %s",
00194 static_cast<int>(status),
00195 return_status_desc(status).c_str());
00196 }
00197 else if (status == ReturnStatuses::OK)
00198 {
00199 buf_size = msg_buf.size();
00200 grand_buffer.insert(grand_buffer.end(), msg_buf.begin(), msg_buf.end());
00201
00202 int first_mw = 0;
00203
00204 while (true)
00205 {
00206 first_mw = find_magic_word(grand_buffer, MAGIC_WORD);
00207
00208 if (first_mw == -1)
00209 {
00210 break;
00211 }
00212 else
00213 {
00214 if (first_mw > 0)
00215 grand_buffer.erase(
00216 grand_buffer.begin(),
00217 grand_buffer.begin() + first_mw);
00218
00219
00220
00221 IbeoDataHeader header;
00222 header.parse(std::vector<uint8_t>(grand_buffer.begin(), grand_buffer.begin() + IBEO_HEADER_SIZE));
00223
00224 auto total_msg_size = IBEO_HEADER_SIZE + header.message_size;
00225
00226 if (grand_buffer.size() < total_msg_size)
00227 break;
00228
00229 std::vector<uint8_t> msg(
00230 grand_buffer.begin(),
00231 grand_buffer.begin() + total_msg_size);
00232 messages.push(msg);
00233 grand_buffer.erase(
00234 grand_buffer.begin(),
00235 grand_buffer.begin() + total_msg_size);
00236 }
00237
00238 if (!ros::ok())
00239 break;
00240 }
00241 }
00242
00243 while (!messages.empty())
00244 {
00245 auto message = messages.front();
00246
00247 network_interface::TCPFrame raw_frame;
00248 raw_frame.address = ip_address;
00249 raw_frame.port = port;
00250 raw_frame.size = message.size();
00251 raw_frame.data.insert(raw_frame.data.end(), message.begin(), message.end());
00252 raw_frame.header.frame_id = frame_id;
00253 raw_frame.header.stamp = ros::Time::now();
00254
00255 raw_tcp_pub.publish(raw_frame);
00256
00257 IbeoDataHeader ibeo_header;
00258 ibeo_header.parse(message);
00259
00260
00261 auto class_parser = IbeoTxMessage::make_message(ibeo_header.data_type_id);
00262
00263 auto pub = pub_list.find(ibeo_header.data_type_id);
00264
00265
00266 if (class_parser != NULL && pub != pub_list.end())
00267 {
00268
00269 class_parser->parse(message);
00270
00271 handler.fillAndPublish(ibeo_header.data_type_id, frame_id, pub->second, class_parser.get());
00272
00273 if (class_parser->has_scan_points)
00274 {
00275 pcl::PointCloud<pcl::PointXYZL> pcl_cloud;
00276 pcl_cloud.header.frame_id = frame_id;
00277
00278 pcl_conversions::toPCL(ros::Time::now(), pcl_cloud.header.stamp);
00279 std::vector<Point3DL> scan_points = class_parser->get_scan_points();
00280 handler.fillPointcloud(scan_points, &pcl_cloud);
00281 pointcloud_pub.publish(pcl_cloud);
00282 }
00283
00284 if (class_parser->has_contour_points)
00285 {
00286 visualization_msgs::Marker marker;
00287 marker.header.frame_id = frame_id;
00288 marker.header.stamp = ros::Time::now();
00289 std::vector<Point3D> contour_points = class_parser->get_contour_points();
00290
00291 if (contour_points.size() > 0)
00292 {
00293 handler.fillContourPoints(contour_points, &marker, frame_id);
00294 object_contour_points_pub.publish(marker);
00295 }
00296 }
00297
00298 if (class_parser->has_objects)
00299 {
00300 std::vector<IbeoObject> objects = class_parser->get_objects();
00301 visualization_msgs::MarkerArray marker_array;
00302 handler.fillMarkerArray(objects, &marker_array, frame_id);
00303
00304 for (visualization_msgs::Marker m : marker_array.markers)
00305 {
00306 m.header.frame_id = frame_id;
00307 }
00308
00309 object_markers_pub.publish(marker_array);
00310 }
00311 }
00312
00313 messages.pop();
00314 }
00315 }
00316 }
00317
00318 loop_rate.sleep();
00319
00320 }
00321
00322 status = tcp_interface.close();
00323
00324 if (status != ReturnStatuses::OK)
00325 ROS_ERROR(
00326 "Ibeo LUX - Closing the connection to the LUX failed: %i - %s",
00327 static_cast<int>(status),
00328 return_status_desc(status).c_str());
00329
00330 return 0;
00331 }