51 #pragma warning(disable: 4996) 52 #pragma warning(disable: 4267) 53 #pragma warning(disable: 4101) // C4101: "e" : Unreferenzierte lokale Variable 54 #define _WIN32_WINNT 0x0501 62 #include <boost/asio.hpp> 63 #include <boost/lambda/lambda.hpp> 66 #include <boost/lexical_cast.hpp> 71 #include "sick_scan/rosconsole_simu.hpp" 83 return(diagnostic_msgs::DiagnosticStatus::ERROR);
88 bool emulateReply(
UINT8*requestData,
int requestLen, std::vector<unsigned char>* replyVector)
92 std::vector<std::string> keyWordList;
93 std::vector<std::string> answerList;
95 keyWordList.push_back(
"sMN SetAccessMode");
96 answerList.push_back(
"sAN SetAccessMode 1");
98 keyWordList.push_back(
"sWN EIHstCola");
99 answerList.push_back(
"sWA EIHstCola");
101 keyWordList.push_back(
"sRN FirmwareVersion");
102 answerList.push_back(
"sRA FirmwareVersion 8 1.0.0.0R");
104 keyWordList.push_back(
"sRN OrdNum");
105 answerList.push_back(
"sRA OrdNum 7 1234567");
107 keyWordList.push_back(
"sWN TransmitTargets 1");
108 answerList.push_back(
"sWA TransmitTargets");
110 keyWordList.push_back(
"sWN TransmitObjects 1");
111 answerList.push_back(
"sWA TransmitObjects");
113 keyWordList.push_back(
"sWN TCTrackingMode 0");
114 answerList.push_back(
"sWA TCTrackingMode");
116 keyWordList.push_back(
"sRN SCdevicestate");
117 answerList.push_back(
"sRA SCdevicestate 1");
119 keyWordList.push_back(
"sRN DItype");
120 answerList.push_back(
"sRA DItype D RMS3xx-xxxxxx");
122 keyWordList.push_back(
"sRN ODoprh");
123 answerList.push_back(
"sRA ODoprh 451");
125 keyWordList.push_back(
"sMN mSCloadappdef");
126 answerList.push_back(
"sAN mSCloadappdef");
129 keyWordList.push_back(
"sRN SerialNumber");
130 answerList.push_back(
"sRA SerialNumber 8 18020073");
132 keyWordList.push_back(
"sMN Run");
133 answerList.push_back(
"sAN Run 1s");
135 keyWordList.push_back(
"sRN ODpwrc");
136 answerList.push_back(
"sRA ODpwrc 20");
138 keyWordList.push_back(
"sRN LocationName");
139 answerList.push_back(
"sRA LocationName B not defined");
141 keyWordList.push_back(
"sEN LMDradardata 1");
142 answerList.push_back(
"sEA LMDradardata 1");
144 for (
int i = 0; i < requestLen; i++)
146 request += (char)requestData[i];
148 for (
int i = 0; i < keyWordList.size(); i++)
150 if (request.find(keyWordList[i]) != std::string::npos)
153 reply += answerList[i];
158 replyVector->clear();
159 for (
int i = 0; i < reply.length(); i++)
161 replyVector->push_back((
unsigned char)reply[i]);
173 socket_(io_service_),
174 deadline_(io_service_),
177 timelimit_(timelimit)
181 if ((cola_dialect_id ==
'a') || (cola_dialect_id ==
'A'))
186 if ((cola_dialect_id ==
'b') || (cola_dialect_id ==
'B'))
201 deadline_.expires_at(boost::posix_time::pos_infin);
212 using boost::asio::ip::tcp;
213 using boost::lambda::var;
214 using boost::lambda::_1;
248 if ((cola_dialect_id ==
'a') || (cola_dialect_id ==
'A'))
250 this->m_protocol =
CoLa_A;
254 this->m_protocol =
CoLa_B;
309 if (i >= m_numberOfBytesInReceiveBuffer)
312 m_numberOfBytesInReceiveBuffer = 0;
317 UINT32 newLen = m_numberOfBytesInReceiveBuffer - i;
319 m_numberOfBytesInReceiveBuffer = newLen;
332 if (i >= m_numberOfBytesInReceiveBuffer)
354 if (magicWord != 0x02020202)
361 if (magicWord == 0x02020202)
379 memmove(&(m_receiveBuffer[0]), &(m_receiveBuffer[i]), bytesToMove);
388 printInfoMessage(
"SickScanCommonNw::findFrameInReceiveBuffer: Frame cannot be decoded yet, only " +
395 payloadlength = colab::getIntegerFromBuffer<UINT32>(
m_receiveBuffer, pos);
399 if (payloadlength > (
sizeof(m_receiveBuffer) - 9))
402 printWarning(
"SickScanCommonNw::findFrameInReceiveBuffer: Frame too big for receive buffer. Frame discarded with length:" 410 printInfoMessage(
"SickScanCommonNw::findFrameInReceiveBuffer: Frame not complete yet. Waiting for the rest of it (" +
416 frameLen = payloadlength + 9;
430 for (
UINT16 i = 8; i < (frameLen - 1); i++)
434 temp_xor = temp_xor ^ temp;
438 if (temp_xor != checkSum)
440 printWarning(
"SickScanCommonNw::findFrameInReceiveBuffer: Wrong checksum, Frame discarded.");
483 bool beVerboseHere =
false;
484 printInfoMessage(
"SickScanCommonNw::readCallbackFunction(): Called with " +
toString(numOfBytes) +
" available bytes.", beVerboseHere);
488 UINT32 bytesToBeTransferred = numOfBytes;
489 if (remainingSpace < numOfBytes)
491 bytesToBeTransferred = remainingSpace;
501 if (bytesToBeTransferred > 0)
505 m_numberOfBytesInReceiveBuffer += bytesToBeTransferred;
519 printInfoMessage(
"SickScanCommonNw::readCallbackFunction(): No complete frame in input buffer, we are done.", beVerboseHere);
527 printInfoMessage(
"SickScanCommonNw::readCallbackFunction(): Processing a frame of length " + ::
toString(frame.
size()) +
" bytes.", beVerboseHere);
529 UINT32 bytesToMove = m_numberOfBytesInReceiveBuffer - size;
531 m_numberOfBytesInReceiveBuffer = bytesToMove;
549 sscanf(
port_.c_str(),
"%d", &portInt);
554 ROS_INFO(
"Sensor emulation is switched on - network traffic is switched off.");
564 ROS_WARN(
"Disconnecting TCP-Connection.");
585 if (
deadline_.expires_at() <= boost::asio::deadline_timer::traits_type::now())
590 deadline_.expires_at(boost::posix_time::pos_infin);
600 this->
recvQueue.getNumberOfEntriesInQueue();
606 deadline_.expires_from_now(boost::posix_time::milliseconds(timeout_ms));
607 const char end_delim =
static_cast<char>(0x03);
609 ec_ = boost::asio::error::would_block;
616 int waitingTimeInMs = 1;
618 for (i = 0; i < timeout_ms; i += waitingTimeInMs)
620 if (
false == this->
recvQueue.isQueueEmpty())
624 boost::this_thread::sleep(boost::posix_time::milliseconds(waitingTimeInMs));
628 ROS_ERROR(
"no answer received after %zu ms. Maybe sopas mode is wrong.\n",timeout_ms);
634 *bytes_read = datagramWithTimeStamp.
datagram.size();
635 memcpy(buffer, &(datagramWithTimeStamp.
datagram[0]), datagramWithTimeStamp.
datagram.size());
646 ROS_ERROR(
"sendSOPASCommand: socket not open");
653 bool cmdIsBinary =
false;
661 for (
int i = 0; i < 4; i++) {
662 if (request[i] == 0x02)
669 if (preambelCnt < 4) {
677 if (cmdIsBinary ==
false)
679 msgLen = strlen(request);
684 for (
int i = 4; i < 8; i++)
686 dataLen |= ((
unsigned char)request[i] << (7 - i) * 8);
688 msgLen = 8 + dataLen + 1;
697 bool debugBinCmd =
false;
700 printf(
"=== START HEX DUMP ===\n");
701 for (
int i = 0; i < msgLen; i++)
703 unsigned char *ptr = (
UINT8*)request;
704 printf(
"%02x ", ptr[i]);
706 printf(
"\n=== END HEX DUMP ===\n");
717 boost::asio::write(
socket_, boost::asio::buffer(request, msgLen));
719 catch (boost::system::system_error &e)
721 ROS_ERROR(
"write error for command: %s", request);
729 const int BUF_SIZE = 65536;
730 char buffer[BUF_SIZE];
749 reply->resize(bytes_read);
751 std::copy(buffer, buffer + bytes_read, &(*reply)[0]);
759 bool isBinaryProtocol,
int *numberOfRemainingFifoEntries)
761 if (NULL != numberOfRemainingFifoEntries)
763 *numberOfRemainingFifoEntries = 0;
771 uint32_t nanoSec = timeStamp.
nsec;
772 double waitTime10Hz = 10.0 * (double)nanoSec / 1E9;
774 uint32_t waitTime = (int)waitTime10Hz ;
776 double waitTimeUntilNextTime10Hz = 1/10.0 * (1.0 - (waitTime10Hz - waitTime));
787 std::vector<unsigned char> dataBuffer;
788 #if 1 // prepared for reconnect 789 bool retVal = this->
recvQueue.waitForIncomingObject(maxWaitInMs);
792 ROS_WARN(
"Timeout during waiting for new datagram");
801 if (NULL != numberOfRemainingFifoEntries)
803 *numberOfRemainingFifoEntries = this->
recvQueue.getNumberOfEntriesInQueue();
805 recvTimeStamp = datagramWithTimeStamp.
timeStamp;
806 dataBuffer = datagramWithTimeStamp.
datagram;
811 long size = dataBuffer.size();
812 memcpy(receiveBuffer, &(dataBuffer[0]), size);
813 *actual_length = size;
818 char szFileName[255];
819 sprintf(szFileName,
"/tmp/dg%06d.bin", cnt++);
823 fout = fopen(szFileName,
"wb");
826 fwrite(receiveBuffer, size, 1, fout);
833 ROS_ERROR(
"get_datagram: socket not open");
841 std::vector<unsigned char> reply;
845 bool exception_occured =
false;
847 char *buffer =
reinterpret_cast<char *
>(receiveBuffer);
851 ROS_ERROR_THROTTLE(1.0,
"get_datagram: no data available for read after %zu ms", timeout);
862 ROS_INFO(
"Failure - attempting to reconnect");
SickScanCommonTcp(const std::string &hostname, const std::string &port, int &timelimit, SickGenericParser *parser, char cola_dialect_id)
std::vector< unsigned char > exampleData(65536)
virtual ~SickScanCommonTcp()
int getReadTimeOutInMs()
get timeout in milliseconds
bool emulateReply(UINT8 *requestData, int requestLen, std::vector< unsigned char > *replyVector)
bool init(std::string ipAddress, unsigned short portNumber, Tcp::DisconnectFunction disconnectFunction, void *obj)
boost::asio::ip::tcp::socket socket_
static int getDiagnosticErrorCode()
void sendCommandBuffer(UINT8 *buffer, UINT16 len)
virtual int get_datagram(ros::Time &recvTimeStamp, unsigned char *receiveBuffer, int bufferSize, int *actual_length, bool isBinaryProtocol, int *numberOfRemainingFifoEntries)
Read a datagram from the device.
bool getEmulSensor()
get emulation flag (using emulation instead of "real" scanner - currently implemented for radar ...
static void readCallbackFunctionS(void *obj, UINT8 *buffer, UINT32 &numOfBytes)
#define printInfoMessage(a, b)
bool setReadCallbackFunction(Tcp::ReadFunction readFunction, void *obj)
void setEmulation(bool _emul)
virtual int sendSOPASCommand(const char *request, std::vector< unsigned char > *reply, int cmdLen)
Send a SOPAS command to the device and print out the response to the console.
static void disconnectFunctionS(void *obj)
BYTE * getRawData()
get SOPAS raw data include header and CRC
diagnostic_updater::Updater diagnostics_
int getProtocolType(void)
get protocol type as enum
#define ROS_INFO_THROTTLE(period,...)
void disconnectFunction()
Queue< DatagramWithTimeStamp > recvQueue
UINT32 m_alreadyReceivedBytes
void setProtocolType(SopasProtocol cola_dialect_id)
set protocol type as enum
void simulateAsciiDatagram(unsigned char *receiveBuffer, int *actual_length)
#define ROS_ERROR_THROTTLE(period,...)
std::vector< unsigned char > datagram
boost::asio::deadline_timer deadline_
UINT32 m_numberOfBytesInReceiveBuffer
Number of bytes in buffer.
void setReplyMode(int _mode)
void readCallbackFunction(UINT8 *buffer, UINT32 &numOfBytes)
Unknown Command Language.
boost::system::error_code ec_
static long receivedDataLen
int numberOfDatagramInInputFifo()
void processFrame(ros::Time timeStamp, SopasEventMessage &frame)
Class that represents a message that was sent by a sensor. (Event message)
virtual int close_device()
virtual int init()
init routine of scanner
bool connect()
Connects to a sensor via tcp and reads the device name.
bool disconnect()
Closes the connection to the LMS. This is the opposite of init().
virtual int init_device()
SopasEventMessage findFrameInReceiveBuffer()
virtual int stop_scanner()
Stops sending scan data.
Mutex m_receiveDataMutex
Access mutex for buffer.
void broadcast(int lvl, const std::string msg)
void setEmulSensor(bool _emulFlag)
Set emulation flag (using emulation instead of "real" scanner - currently implemented for radar...
UINT8 m_receiveBuffer[480000]
Low-Level receive buffer for all data.
std::vector< unsigned char > receivedData(65536)
int readWithTimeout(size_t timeout_ms, char *buffer, int buffer_size, int *bytes_read=0, bool *exception_occured=0, bool isBinary=false)
void printWarning(std::string message)
void handleRead(boost::system::error_code error, size_t bytes_transfered)