00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "LaserScanner.hpp"
00019 #include "SickLMS200.h"
00020 #include <rtt/Logger.hpp>
00021 #include <iostream>
00022 #include <ocl/ComponentLoader.hpp>
00023
00024 ORO_CREATE_COMPONENT( OCL::LaserScanner );
00025
00026 namespace OCL
00027 {
00028 using namespace RTT;
00029 using namespace std;
00030 using namespace SickDriver;
00031
00032 LaserScanner::LaserScanner(string name):
00033 TaskContext(name),
00034 port("port","Serial port to which the Sick scanner is connected. (/dev/ttySx)","/dev/ttyS0"),
00035 range_mode("range_mode","Should be 100 or 180 degrees",180),
00036 res_mode("res_mode","Should be 0.25,0.5,1 degrees",0.5),
00037 unit_mode("unit_mode","Should be mm or cm","mm"),
00038 distances("LaserDistance"),
00039 angles("LaserAngle"),
00040 distanceOutOfRange("distanceOutOfRange")
00041 {
00042 log(Debug) <<this->TaskContext::getName()<<": adding Properties"<<endlog();
00043 properties()->addProperty(&port);
00044 properties()->addProperty(&range_mode);
00045 properties()->addProperty(&res_mode);
00046 properties()->addProperty(&unit_mode);
00047
00048 log(Debug) <<this->TaskContext::getName()<<": adding Ports"<<endlog();
00049 ports()->addPort(&distances);
00050 ports()->addPort(&angles);
00051
00052 log(Debug) <<this->TaskContext::getName()<<": adding Events"<<endlog();
00053 events()->addEvent(&distanceOutOfRange, "Distance out of Range", "C", "Channel", "V", "Value");
00054
00055 log(Debug) <<this->TaskContext::getName()<<": constructed."<<endlog();
00056 buf = new unsigned char[MAXNDATA];
00057 }
00058
00059
00060 LaserScanner::~LaserScanner()
00061 {
00062 sick_laserscanner->stop();
00063 delete buf;
00064 delete sick_laserscanner;
00065 }
00066
00067 bool LaserScanner::configureHook()
00068 {
00069 Logger::In in(this->TaskContext::getName());
00070
00071 log(Debug) <<this->TaskContext::getName()<<": create Sick laserscanner"<<endlog();
00072 port_char = port.value().c_str();
00073
00074 if (range_mode.value() == 100 )
00075 range_mode_char = SickLMS200::RANGE_100;
00076 else if (range_mode.value() == 180 )
00077 range_mode_char = SickLMS200::RANGE_180;
00078 else {
00079 log(Error) <<"Wrong range parameter. Should be 100 or 180."<<endlog();
00080 return false;
00081 }
00082
00083 if (res_mode.value() == 1.0 )
00084 res_mode_char = SickLMS200::RES_1_DEG;
00085 else if (res_mode.value() == 0.5 )
00086 res_mode_char = SickLMS200::RES_0_5_DEG;
00087 else if (res_mode.value() == 0.25 && range_mode.value() == 100 )
00088 res_mode_char = SickLMS200::RES_0_25_DEG;
00089 else if (res_mode.value() == 0.25 && range_mode.value() == 180 ) {
00090 log(Error) <<" Res 0.25 does not work with range mode 180."<<endlog();
00091 return false;
00092 } else{
00093 log(Error) <<"Wrong res_mode parameter. Should be 0.25 or 0.5 or 1.0."<<endlog();
00094 return false;
00095 }
00096
00097 if (unit_mode.value() == "cm" )
00098 unit_mode_char = SickLMS200::CMMODE;
00099 else if (unit_mode.value() == "mm" )
00100 unit_mode_char = SickLMS200::MMMODE;
00101 else {
00102 log(Error)<<"Wrong unit mode parameter. Should be cm or mm."<<endlog();
00103 return false;
00104 }
00105
00106 num_meas = (unsigned int)(range_mode.value()/res_mode.value())+1;
00107 distances_local.resize(num_meas);
00108 angles_local.resize(num_meas);
00109 for (unsigned int i=0; i<num_meas; i++)
00110 angles_local[i] = ((double)i/((double)num_meas-1.0))*(double)(range_mode.value()*M_PI/180);
00111
00112 sick_laserscanner = new SickLMS200(port_char, range_mode_char, res_mode_char, unit_mode_char);
00113 return true;
00114 }
00115
00116
00117 bool LaserScanner::startHook()
00118 {
00119 Logger::In in(this->TaskContext::getName());
00120 if (!sick_laserscanner->start()){
00121 log(Error)<<"Starting laserscanner failed."<<endlog();
00122 return false;
00123 }
00124
00125 if (!registerSickLMS200SignalHandler()){
00126 log(Error)<<"Register Sick signal handler failed."<<endlog();
00127 return false;
00128 }
00129
00130 angles.Set(angles_local);
00131
00132 return true;
00133 }
00134
00135
00136 void LaserScanner::updateHook()
00137 {
00138 sick_laserscanner->readMeasurement(buf,datalen);
00139
00140 if (sick_laserscanner->checkErrorMeasurement()){
00141 log(Error)<<"Measurement error."<<endlog();
00142 error();
00143 }
00144
00145 if (!sick_laserscanner->checkPlausible()){
00146 log(Warning)<<"Measurement not reliable."<<endlog();
00147 warning();
00148 }
00149
00150 if (num_meas*2 != (unsigned int)datalen){
00151 log(Error)<<"Number of measurements inconsistent: expected "
00152 << num_meas << " and received " << datalen/2 <<endlog();
00153 warning();
00154 }
00155
00156 for (int i=0; i<datalen; i=i+2)
00157 distances_local[(unsigned int)(i/2)] = ((double)( (buf[i+1] & 0x1f) <<8 |buf[i]))/1000.0;
00158 distances.Set(distances_local);
00159
00160 this->engine()->getActivity()->trigger();
00161 }
00162
00163 void LaserScanner::stopHook()
00164 {
00165 if (!sick_laserscanner->stop())
00166 log(Error)<<"Error stopping laserscanner"<<endlog();
00167 }
00168 }
00169