66 #define DELETE_PTR(p) do{if(p){delete(p);(p)=0;}}while(false)
81 ROS_ERROR_STREAM(
"## ERROR sick_scansegment_xd::run(" <<
config.scanner_type <<
"): Config::Init() failed, using default values.");
87 std::vector<int> layer_elevation_table_mdeg = { 22710, 17560, 12480, 7510, 2490, 70, -2430, -7290, -12790, -17280, -21940, -26730, -31860, -34420, -37180, -42790 };
95 ROS_ERROR_STREAM(
"## ERROR sick_scansegment_xd::run(" <<
config.scanner_type <<
"): sick_scansegment_xd::MsgPackThreads::start() failed");
100 msgpack_threads.
join();
105 if(!msgpack_threads.
stop(
false))
107 ROS_ERROR_STREAM(
"## ERROR sick_scansegment_xd::run(" <<
config.scanner_type <<
"): sick_scansegment_xd::MsgPackThreads::stop() failed");
109 std::cout <<
"sick_scansegment_xd (" <<
config.scanner_type <<
") finished." << std::endl;
117 : m_scansegment_thread(0), m_run_scansegment_thread(false)
135 m_run_scansegment_thread =
true;
145 m_run_scansegment_thread =
false;
146 if(m_scansegment_thread)
148 if (do_join && m_scansegment_thread->joinable())
149 m_scansegment_thread->join();
150 delete m_scansegment_thread;
151 m_scansegment_thread = 0;
161 if(m_scansegment_thread && m_scansegment_thread->joinable())
163 m_scansegment_thread->join();
164 std::cout <<
"sick_scansegment_xd::join(): sick_scansegment_xd thread finished" << std::endl;
173 ROS_INFO_STREAM(
"sick_scansegment_xd::runThreadCb() start (" << __LINE__ <<
"," << (
int)m_run_scansegment_thread <<
"," << (
int)
rosOk() <<
")...");
174 if(!m_config.logfolder.empty() && m_config.logfolder !=
".")
180 while(m_run_scansegment_thread &&
rosOk())
186 while(m_run_scansegment_thread &&
rosOk() && udp_receiver == 0)
189 if(udp_receiver->
Init(m_config.udp_sender, m_config.udp_port, m_config.udp_input_fifolength, m_config.verbose_level > 1, m_config.export_udp_msg, m_config.scandataformat, 0))
191 ROS_INFO_STREAM(
"sick_scansegment_xd: udp socket to " << m_config.udp_sender <<
":" << m_config.udp_port <<
" initialized");
195 ROS_ERROR_STREAM(
"## ERROR sick_scansegment_xd: UdpReceiver::Init(" << m_config.udp_sender <<
"," << m_config.udp_port <<
") failed, retrying...");
196 delete(udp_receiver);
204 while(m_run_scansegment_thread &&
rosOk() && m_config.imu_enable && m_config.scandataformat ==
SCANDATA_COMPACT && udp_receiver_imu == 0)
207 if(udp_receiver_imu->
Init(m_config.udp_sender, m_config.imu_udp_port, m_config.udp_input_fifolength, m_config.verbose_level > 1, m_config.export_udp_msg, m_config.scandataformat, udp_receiver->
Fifo()))
210 ROS_INFO_STREAM(
"sick_scansegment_xd: udp socket to " << m_config.udp_sender <<
":" << m_config.imu_udp_port <<
" initialized");
214 ROS_ERROR_STREAM(
"## ERROR sick_scansegment_xd: UdpReceiver::Init(" << m_config.udp_sender <<
"," << m_config.imu_udp_port <<
") failed, retrying...");
215 delete(udp_receiver_imu);
216 udp_receiver_imu = 0;
224 sick_scansegment_xd::MsgPackConverter msgpack_converter(scansegment_parser_config, m_config.add_transform_xyz_rpy, udp_receiver->
Fifo(), m_config.scandataformat, m_config.msgpack_output_fifolength, m_config.verbose_level > 1);
225 assert(udp_receiver->
Fifo());
226 assert(msgpack_converter.
Fifo());
230 std::shared_ptr<sick_scansegment_xd::RosMsgpackPublisher> ros_msgpack_publisher = std::make_shared<sick_scansegment_xd::RosMsgpackPublisher>(
"sick_scansegment_xd", m_config);
235 if (msgpack_converter.
Start() && udp_receiver->
Start() && msgpack_exporter.
Start())
237 ROS_INFO_STREAM(
"MsgPackThreads: Start msgpack converter, udp receiver and msgpack exporter, receiving from " << m_config.udp_sender <<
":" << m_config.udp_port);
238 if (udp_receiver_imu)
240 if (udp_receiver_imu->
Start())
241 ROS_INFO_STREAM(
"MsgPackThreads: udp receiver for imu data started, receiving from " << m_config.udp_sender <<
":" << m_config.imu_udp_port);
243 ROS_ERROR_STREAM(
"## ERROR sick_scansegment_xd: UdpReceiver::Start() failed for imu data, not receiving imu udp packages from " << m_config.udp_sender <<
":" << m_config.imu_udp_port);
248 ROS_ERROR_STREAM(
"## ERROR sick_scansegment_xd: MsgPackConverter::Start(), UdpReceiver::Start() or MsgPackExporter::Start() failed, not receiving udp packages from " << m_config.udp_sender <<
":" << m_config.udp_port);
258 bool multiscan_write_filtersettings = m_config.host_set_FREchoFilter || m_config.host_set_LFPangleRangeFilter || m_config.host_set_LFPlayerFilter;
259 if (m_config.start_sopas_service || m_config.send_sopas_start_stop_cmd || m_config.host_read_filtersettings || multiscan_write_filtersettings)
261 ROS_INFO_STREAM(
"MsgPackThreads: initializing sopas tcp (" << m_config.hostname <<
":" << m_config.sopas_tcp_port <<
", timeout:" << (0.001*m_config.sopas_timeout_ms) <<
", binary:" << m_config.sopas_cola_binary <<
")");
262 sopas_tcp =
new sick_scan_xd::SickScanCommonTcp(m_config.hostname, m_config.sopas_tcp_port, m_config.sopas_timeout_ms, m_config.node, &
parser, m_config.sopas_cola_binary ?
'B' :
'A');
276 if ((m_config.host_read_filtersettings || multiscan_write_filtersettings) && sopas_tcp && sopas_service)
281 if (multiscan_write_filtersettings)
284 sopas_service->writeMultiScanFiltersettings((m_config.host_set_FREchoFilter ? m_config.host_FREchoFilter : -1),
285 (m_config.host_set_LFPangleRangeFilter ? m_config.host_LFPangleRangeFilter :
""),
286 (m_config.host_set_LFPlayerFilter ? m_config.host_LFPlayerFilter :
""),
287 (m_config.host_set_LFPintervalFilter ? m_config.host_LFPintervalFilter :
""),
288 m_config.scanner_type);
292 if (sopas_service->queryMultiScanFiltersettings(m_config.host_FREchoFilter, m_config.host_LFPangleRangeFilter, m_config.host_LFPlayerFilter, m_config.msgpack_validator_filter_settings, m_config.scanner_type))
295 bool angle_range_filter_enabled = ros_msgpack_publisher->initLFPangleRangeFilterSettings(m_config.host_LFPangleRangeFilter);
296 bool layer_filter_enabled = ros_msgpack_publisher->initLFPlayerFilterSettings(m_config.host_LFPlayerFilter);
297 float fullframe_azimuth_min_deg = 0, fullframe_azimuth_max_deg = 0, fullframe_elevation_min_deg = 0, fullframe_elevation_max_deg = 0;
298 ros_msgpack_publisher->GetFullframeAngleRanges(fullframe_azimuth_min_deg, fullframe_azimuth_max_deg, fullframe_elevation_min_deg, fullframe_elevation_max_deg);
299 if (angle_range_filter_enabled)
300 ROS_INFO_STREAM(
"expected azimuth range of fullframe scans: " << std::fixed << std::setprecision(3) << fullframe_azimuth_min_deg <<
" to " << fullframe_azimuth_max_deg <<
" deg");
301 if (layer_filter_enabled)
302 ROS_INFO_STREAM(
"expected elevation range of fullframe scans: " << std::fixed << std::setprecision(3) << fullframe_elevation_min_deg <<
" to " << fullframe_elevation_max_deg <<
" deg");
307 ROS_WARN_STREAM(
"## ERROR sick_scansegment_xd: no sopas tcp connection, multiScan136 filter settings not queried or written");
314 m_config.msgpack_validator_filter_settings.msgpack_validator_azimuth_start, m_config.msgpack_validator_filter_settings.msgpack_validator_azimuth_end,
315 m_config.msgpack_validator_filter_settings.msgpack_validator_elevation_start, m_config.msgpack_validator_filter_settings.msgpack_validator_elevation_end,
316 m_config.msgpack_validator_valid_segments, m_config.msgpack_validator_filter_settings.msgpack_validator_layer_filter,
317 m_config.msgpack_validator_verbose);
318 msgpack_converter.
SetValidator(msgpack_validator, m_config.msgpack_validator_enabled, m_config.msgpack_validator_discard_msgpacks_out_of_bounds, m_config.msgpack_validator_check_missing_scandata_interval);
320 ros_msgpack_publisher->SetActive(
true);
323 if(sopas_tcp && sopas_service && m_config.send_sopas_start_stop_cmd)
328 if (!sopas_service->sendMultiScanStartCmd(m_config.udp_receiver_ip, m_config.udp_port, m_config.scanner_type, m_config.scandataformat, m_config.imu_enable, m_config.imu_udp_port,
329 m_config.performanceprofilenumber, m_config.check_udp_receiver_ip, m_config.check_udp_receiver_port))
331 ROS_ERROR_STREAM(
"## ERROR sick_scansegment_xd: failed to send startup sequence, receiving scan data may fail.");
336 ROS_ERROR_STREAM(
"## ERROR sick_scansegment_xd: no sopas tcp connection, startup sequence not sent, receiving scan data may fail.");
349 std::this_thread::sleep_for(std::chrono::milliseconds(10));
352 while(m_run_scansegment_thread &&
rosOk())
356 ROS_ERROR_STREAM(
"## ERROR sick_scansegment_xd: sopas tcp connection lost, stop and reconnect...");
366 ROS_ERROR_STREAM(
"## ERROR sick_scansegment_xd: udp receive timeout, stop and reconnect...");
376 std::this_thread::sleep_for(std::chrono::milliseconds(10));
384 msgpack_exporter.
Stop();
385 if (udp_receiver_imu)
387 udp_receiver_imu->
Close();
390 udp_receiver->
Stop();
395 if(sopas_tcp && sopas_service && m_config.send_sopas_start_stop_cmd && sopas_tcp->
isConnected())
397 std::cout <<
"sick_scansegment_xd exit: sending stop commands..." << std::endl;
399 sopas_service->sendMultiScanStopCmd(m_config.imu_enable);
400 std::cout <<
"sick_scansegment_xd exit: stop commands sent." << std::endl;
403 std::cout <<
"sick_scansegment_xd exit: stopping services and communication (" << __LINE__ <<
")" << std::endl;
409 msgpack_converter.
Fifo()->Shutdown();
410 msgpack_exporter.
Close();
411 msgpack_converter.
Close();
412 udp_receiver->
Close();
414 std::cout <<
"sick_scansegment_xd exit: services and communication stopped (" << __LINE__ <<
")" << std::endl;
416 catch(
const std::exception& e)
418 std::cerr <<
"## ERROR sick_scansegment_xd exit: exception \"" << e.what() <<
"\"" << std::endl;
422 ROS_INFO_STREAM(
"sick_scansegment_xd::runThreadCb() finished (" << __LINE__ <<
")");