sick_mrs1000_communication.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2017, Osnabrück University
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of Osnabrück University nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  *
00029  *      Author:
00030  *         Sebastian Pütz <spuetz@uos.de>
00031  *
00032  */
00033 
00034 #include "sick_tim/sick_mrs1000_communication.h"
00035 
00036 namespace sick_tim
00037 {
00038 
00039 SickMrs1000Communication::SickMrs1000Communication(const std::string &hostname,
00040                                                    const std::string &port,
00041                                                    int &timelimit,
00042                                                    ScanAndCloudParser* parser)
00043 : SickTimCommonTcp(hostname, port, timelimit, parser),
00044   scan_and_cloud_parser_(parser),
00045   cloud_pub_(nh_.advertise<sensor_msgs::PointCloud2>("cloud", 300)),
00046   diagnosed_cloud_publisher_(cloud_pub_, diagnostics_,
00047     diagnostic_updater::FrequencyStatusParam(&expectedFrequency_, &expectedFrequency_, 0.1, 10),
00048     diagnostic_updater::TimeStampStatusParam(-1, 1.3 * 1.0/expectedFrequency_ - config_.time_offset)
00049   )
00050 {
00051   expectedFrequency_ = 12.5; // by data sheet 50 Hz, 4 x 12,5 Hz
00052 }
00053 
00054 SickMrs1000Communication::~SickMrs1000Communication()
00055 {
00056 
00057 
00058 }
00059 
00060 int SickMrs1000Communication::loopOnce()
00061 {
00062   diagnostics_.update();
00063 
00064   unsigned char receiveBuffer[65536];
00065   int actual_length = 0;
00066   static unsigned int iteration_count = 0;
00067 
00068   int result = get_datagram(receiveBuffer, 65536, &actual_length);
00069   if (result != 0)
00070   {
00071     ROS_ERROR("Read Error when getting datagram: %i.", result);
00072     diagnostics_.broadcast(diagnostic_msgs::DiagnosticStatus::ERROR, "Read Error when getting datagram.");
00073     return ExitError; // return failure to exit node
00074   }
00075   if(actual_length <= 0)
00076     return ExitSuccess; // return success to continue looping
00077 
00078   // ----- if requested, skip frames
00079   if (iteration_count++ % (config_.skip + 1) != 0)
00080     return ExitSuccess;
00081 
00082   if (publish_datagram_)
00083   {
00084     std_msgs::String datagram_msg;
00085     datagram_msg.data = std::string(reinterpret_cast<char*>(receiveBuffer));
00086     datagram_pub_.publish(datagram_msg);
00087   }
00088 
00089   sensor_msgs::LaserScan scan;
00090 
00091   /*
00092    * datagrams are enclosed in <STX> (0x02), <ETX> (0x03) pairs
00093    */
00094   char* buffer_pos = (char*)receiveBuffer;
00095   char *dstart, *dend;
00096   while( (dstart = strchr(buffer_pos, 0x02)) && (dend = strchr(dstart + 1, 0x03)) )
00097   {
00098     size_t dlength = dend - dstart;
00099     *dend = '\0';
00100     dstart++;
00101     sensor_msgs::PointCloud2 cloud;
00102     int success = scan_and_cloud_parser_->parse_datagram(dstart, dlength, config_, scan, cloud);
00103 
00104     if (success == ExitSuccess)
00105     {
00106 
00107       /*
00108        * cloud.header.frame_id == "" means we're still accumulating
00109        * the layers of the point cloud, so don't publish yet.
00110        */
00111       if(cloud.header.frame_id != "")
00112       {
00113         ROS_DEBUG_STREAM("Publish cloud with " << cloud.height * cloud.width
00114           << " points in the frame \"" << cloud.header.frame_id << "\".");
00115         diagnosed_cloud_publisher_.publish(cloud);
00116       }
00117 
00118       /*
00119        * scan.header.frame_id == "" means the laser scan was of a layer
00120        * different than layer 0, so don't publish it (because the points
00121        * don't lie in a plane)
00122        */
00123       if(scan.header.frame_id != "")
00124       {
00125         diagnosticPub_->publish(scan);
00126       }
00127 
00128     }
00129     buffer_pos = dend + 1;
00130   }
00131 
00132   return ExitSuccess; // return success to continue looping
00133 }
00134 
00135 int SickMrs1000Communication::init_scanner()
00136 {
00137   int init_base = SickTimCommonTcp::init_scanner();
00138   if(init_base != ExitSuccess)
00139   {
00140     return init_base;
00141   }
00142 
00143   /*
00144    * Set Maintenance access mode to allow mode change to be sent
00145    */
00146   std::vector<unsigned char> access_reply;
00147   int result = sendSOPASCommand("\x02sMN SetAccessMode 03 F4724744\x03\0", &access_reply);
00148   if (result != 0)
00149   {
00150     ROS_ERROR("SOPAS - Error setting access mode");
00151     diagnostics_.broadcast(diagnostic_msgs::DiagnosticStatus::ERROR, "SOPAS - Error setting access mode.");
00152     return ExitError;
00153   }
00154   std::string access_reply_str = replyToString(access_reply);
00155   if (access_reply_str != "sAN SetAccessMode 1")
00156   {
00157     ROS_ERROR_STREAM("SOPAS - Error setting access mode, unexpected response : " << access_reply_str);
00158     diagnostics_.broadcast(diagnostic_msgs::DiagnosticStatus::ERROR, "SOPAS - Error setting access mode.");
00159     return ExitError;
00160   }
00161 
00162   /*
00163    * Application selection and switching 'sWN SetActiveApplication'
00164    */
00165   const char setActiveApplication[] = {"\x02sWN SetActiveApplications 1 RANG 1\x03\0"};
00166   std::vector<unsigned char> activeApplicationReply;
00167   result = sendSOPASCommand(setActiveApplication, &activeApplicationReply);
00168   if (result != 0)
00169   {
00170     ROS_ERROR("SOPAS - SetActiveApplications failed 'sWN SetActiveApplications'.");
00171     diagnostics_.broadcast(diagnostic_msgs::DiagnosticStatus::ERROR, "SOPAS - 'sWN SetActiveApplications 1 RANG 1'.");
00172     return ExitError;
00173   }
00174   std::string activeApplicationReplyStr = replyToString(activeApplicationReply);
00175   ROS_INFO_STREAM("active application reply: " << activeApplicationReplyStr);
00176 
00177   /*
00178    * Start streaming 'LMDscandata'.
00179    */
00180   const char requestScanData[] = {"\x02sEN LMDscandata 1\x03\0"};
00181   result = sendSOPASCommand(requestScanData, NULL);
00182   if (result != 0)
00183   {
00184     ROS_ERROR("SOPAS - Error starting to stream 'LMDscandata'.");
00185     diagnostics_.broadcast(diagnostic_msgs::DiagnosticStatus::ERROR, "SOPAS - Error starting to stream 'LMDscandata'.");
00186     return ExitError;
00187   }
00188 
00189   return ExitSuccess;
00190 
00191 }
00192 
00193 } /* namespace sick_tim */


sick_tim
Author(s): Jochen Sprickerhof , Martin Günther , Sebastian Pütz
autogenerated on Thu May 9 2019 02:32:02