diff --git a/source/RobotAPI/drivers/SickLaserUnit/SickLaserUnit.cpp b/source/RobotAPI/drivers/SickLaserUnit/SickLaserUnit.cpp
index 1897cbf137dd848e60cbe1b16ca49cc1be8ffdce..092cecf1931e0679700bdd95f08924366f078de1 100644
--- a/source/RobotAPI/drivers/SickLaserUnit/SickLaserUnit.cpp
+++ b/source/RobotAPI/drivers/SickLaserUnit/SickLaserUnit.cpp
@@ -45,7 +45,7 @@ namespace armarx
                     if (result == sick_scan::ExitSuccess) // OK -> loop again
                     {
                         ARMARX_INFO_S << "looping";
-                        result = scanner->loopOnce();
+                        result = scanner->loopOnce(scanData);
                         ARMARX_INFO_S << "finished looping";
                     }
                     else
diff --git a/source/RobotAPI/drivers/SickLaserUnit/SickLaserUnit.h b/source/RobotAPI/drivers/SickLaserUnit/SickLaserUnit.h
index 4990eb80c060ddd627d5ccec9e3ef318ea19e181..e6c83c4c8893a26aa42a643e781cecdc07100d62 100644
--- a/source/RobotAPI/drivers/SickLaserUnit/SickLaserUnit.h
+++ b/source/RobotAPI/drivers/SickLaserUnit/SickLaserUnit.h
@@ -26,6 +26,7 @@
 
 #include <ArmarXCore/core/Component.h>
 #include <ArmarXCore/core/services/tasks/RunningTask.h>
+#include <RobotAPI/interface/units/LaserScannerUnit.h>
 // #include <ArmarXCore/libraries/ArmarXCoreComponentPlugins/DebugObserverComponentPlugin.h>
 
 // #include <ArmarXGui/libraries/ArmarXGuiComponentPlugins/LightweightRemoteGuiComponentPlugin.h>
@@ -72,9 +73,12 @@ namespace armarx
         bool useTcp = false;
         char colaDialectId = 'A';
         //data and task pointers
-        std::vector<long> scanData;
+        std::vector<long> lengthData;
+        LaserScan scanData;
         RunState runState = RunState::scannerFinalize;
         RunningTask<SickLaserScanDevice>::pointer_type task;
+
+
         sick_scan::SickScanConfig cfg;
         SickScanAdapter* scanner;
         //sick_scan::SickScanCommonTcp* scanner;
diff --git a/source/RobotAPI/drivers/SickLaserUnit/SickScanAdapter.cpp b/source/RobotAPI/drivers/SickLaserUnit/SickScanAdapter.cpp
index 4466765447c17fc8fa3ae49d470d1566097ed1e9..ae45d3132aac4cace62d5603d979f8f2bb97333e 100644
--- a/source/RobotAPI/drivers/SickLaserUnit/SickScanAdapter.cpp
+++ b/source/RobotAPI/drivers/SickLaserUnit/SickScanAdapter.cpp
@@ -86,7 +86,7 @@
 
 std::vector<unsigned char> exampleData(65536);
 std::vector<unsigned char> receivedData(65536);
-static long receivedDataLen = 0;
+//static long receivedDataLen = 0;
 
 static int getDiagnosticErrorCode()
 {
@@ -102,134 +102,134 @@ namespace armarx
 {
     bool emulateReply(UINT8* requestData, int requestLen, std::vector<unsigned char>* replyVector)
     {
-	std::string request;
-	std::string reply;
-	std::vector<std::string> keyWordList;
-	std::vector<std::string> answerList;
+        std::string request;
+        std::string reply;
+        std::vector<std::string> keyWordList;
+        std::vector<std::string> answerList;
 
-	std::string scannerType = "???";
-	ros::NodeHandle nhPriv;
+        std::string scannerType = "???";
+        ros::NodeHandle nhPriv;
 
-	enum
-	{
-	    SIMU_RADAR = 0, SIMU_MRS_1XXX = 1, SIMU_NUM
-	};
-	// XXX
-	keyWordList.push_back("sMN SetAccessMode");
-	answerList.push_back("sAN SetAccessMode 1");
+        enum
+        {
+            SIMU_RADAR = 0, SIMU_MRS_1XXX = 1, SIMU_NUM
+        };
+        // XXX
+        keyWordList.push_back("sMN SetAccessMode");
+        answerList.push_back("sAN SetAccessMode 1");
 
-	keyWordList.push_back("sWN EIHstCola");
-	answerList.push_back("sWA EIHstCola");
+        keyWordList.push_back("sWN EIHstCola");
+        answerList.push_back("sWA EIHstCola");
 
-	keyWordList.push_back("sRN FirmwareVersion");
-	answerList.push_back("sRA FirmwareVersion 8 1.0.0.0R");
+        keyWordList.push_back("sRN FirmwareVersion");
+        answerList.push_back("sRA FirmwareVersion 8 1.0.0.0R");
 
-	keyWordList.push_back("sRN OrdNum");
-	answerList.push_back("sRA OrdNum 7 1234567");
+        keyWordList.push_back("sRN OrdNum");
+        answerList.push_back("sRA OrdNum 7 1234567");
 
-	keyWordList.push_back("sWN TransmitTargets 1");
-	answerList.push_back("sWA TransmitTargets");
+        keyWordList.push_back("sWN TransmitTargets 1");
+        answerList.push_back("sWA TransmitTargets");
 
-	keyWordList.push_back("sWN TransmitObjects 1");
-	answerList.push_back("sWA TransmitObjects");
+        keyWordList.push_back("sWN TransmitObjects 1");
+        answerList.push_back("sWA TransmitObjects");
 
-	keyWordList.push_back("sWN TCTrackingMode 0");
-	answerList.push_back("sWA TCTrackingMode");
+        keyWordList.push_back("sWN TCTrackingMode 0");
+        answerList.push_back("sWA TCTrackingMode");
 
-	keyWordList.push_back("sRN SCdevicestate");
-	answerList.push_back("sRA SCdevicestate 1");
+        keyWordList.push_back("sRN SCdevicestate");
+        answerList.push_back("sRA SCdevicestate 1");
 
-	keyWordList.push_back("sRN DItype");
-	answerList.push_back("sRA DItype D RMS3xx-xxxxxx");
+        keyWordList.push_back("sRN DItype");
+        answerList.push_back("sRA DItype D RMS3xx-xxxxxx");
 
-	keyWordList.push_back("sRN ODoprh");
-	answerList.push_back("sRA ODoprh 451");
+        keyWordList.push_back("sRN ODoprh");
+        answerList.push_back("sRA ODoprh 451");
 
-	keyWordList.push_back("sMN mSCloadappdef");
-	answerList.push_back("sAN mSCloadappdef");
+        keyWordList.push_back("sMN mSCloadappdef");
+        answerList.push_back("sAN mSCloadappdef");
 
 
-	keyWordList.push_back("sRN SerialNumber");
-	answerList.push_back("sRA SerialNumber 8 18020073");
+        keyWordList.push_back("sRN SerialNumber");
+        answerList.push_back("sRA SerialNumber 8 18020073");
 
-	keyWordList.push_back("sMN Run");
-	answerList.push_back("sAN Run 1s");
+        keyWordList.push_back("sMN Run");
+        answerList.push_back("sAN Run 1s");
 
-	keyWordList.push_back("sRN ODpwrc");
-	answerList.push_back("sRA ODpwrc 20");
+        keyWordList.push_back("sRN ODpwrc");
+        answerList.push_back("sRA ODpwrc 20");
 
-	keyWordList.push_back("sRN LocationName");
-	answerList.push_back("sRA LocationName B not defined");
+        keyWordList.push_back("sRN LocationName");
+        answerList.push_back("sRA LocationName B not defined");
 
-	keyWordList.push_back("sEN LMDradardata 1");
-	answerList.push_back("sEA LMDradardata 1");
+        keyWordList.push_back("sEN LMDradardata 1");
+        answerList.push_back("sEA LMDradardata 1");
 
-	for (int i = 0; i < requestLen; i++)
-	{
-	    request += (char) requestData[i];
-	}
-	for (size_t i = 0; i < keyWordList.size(); i++)
-	{
-	    if (request.find(keyWordList[i]) != std::string::npos)
-	    {
-		reply = (char) 0x02;
-		reply += answerList[i];
-		reply += (char) 0x03;
-	    }
-	}
+        for (int i = 0; i < requestLen; i++)
+        {
+            request += (char) requestData[i];
+        }
+        for (size_t i = 0; i < keyWordList.size(); i++)
+        {
+            if (request.find(keyWordList[i]) != std::string::npos)
+            {
+                reply = (char) 0x02;
+                reply += answerList[i];
+                reply += (char) 0x03;
+            }
+        }
 
-	replyVector->clear();
-	for (size_t i = 0; i < reply.length(); i++)
-	{
-	    replyVector->push_back((unsigned char) reply[i]);
-	}
+        replyVector->clear();
+        for (size_t i = 0; i < reply.length(); i++)
+        {
+            replyVector->push_back((unsigned char) reply[i]);
+        }
 
-	return (true);
+        return (true);
     }
 
 
     SickScanAdapter::SickScanAdapter(const std::string& hostname, const std::string& port, int& timelimit,
-				     sick_scan::SickGenericParser* parser, char cola_dialect_id)
-	:
-	sick_scan::SickScanCommon(parser),
-	socket_(io_service_),
-	deadline_(io_service_),
-	parser_ptr(parser),
-	hostname_(hostname),
-	port_(port),
-	timelimit_(timelimit)
+                                     sick_scan::SickGenericParser* parser, char cola_dialect_id)
+        :
+        sick_scan::SickScanCommon(parser),
+        socket_(io_service_),
+        deadline_(io_service_),
+        parser_ptr(parser),
+        hostname_(hostname),
+        port_(port),
+        timelimit_(timelimit)
     {
 
-	setEmulSensor(false);
-	if ((cola_dialect_id == 'a') || (cola_dialect_id == 'A'))
-	{
-	    this->setProtocolType(CoLa_A);
-	}
+        setEmulSensor(false);
+        if ((cola_dialect_id == 'a') || (cola_dialect_id == 'A'))
+        {
+            this->setProtocolType(CoLa_A);
+        }
 
-	if ((cola_dialect_id == 'b') || (cola_dialect_id == 'B'))
-	{
-	    this->setProtocolType(CoLa_B);
-	}
+        if ((cola_dialect_id == 'b') || (cola_dialect_id == 'B'))
+        {
+            this->setProtocolType(CoLa_B);
+        }
 
-	assert(this->getProtocolType() != CoLa_Unknown);
+        assert(this->getProtocolType() != CoLa_Unknown);
 
-	m_numberOfBytesInReceiveBuffer = 0;
-	m_alreadyReceivedBytes = 0;
-	this->setReplyMode(0);
-	// io_service_.setReadCallbackFunction(boost::bind(&SopasDevice::readCallbackFunction, this, _1, _2));
+        m_numberOfBytesInReceiveBuffer = 0;
+        m_alreadyReceivedBytes = 0;
+        this->setReplyMode(0);
+        // io_service_.setReadCallbackFunction(boost::bind(&SopasDevice::readCallbackFunction, this, _1, _2));
 
-	// Set up the deadline actor to implement timeouts.
-	// Based on blocking TCP example on:
-	// http://www.boost.org/doc/libs/1_46_0/doc/html/boost_asio/example/timeouts/blocking_tcp_client.cpp
-	deadline_.expires_at(boost::posix_time::pos_infin);
-	checkDeadline();
+        // Set up the deadline actor to implement timeouts.
+        // Based on blocking TCP example on:
+        // http://www.boost.org/doc/libs/1_46_0/doc/html/boost_asio/example/timeouts/blocking_tcp_client.cpp
+        deadline_.expires_at(boost::posix_time::pos_infin);
+        checkDeadline();
 
     }
 
     SickScanAdapter::~SickScanAdapter()
     {
-	// stop_scanner();
-	close_device();
+        // stop_scanner();
+        close_device();
     }
 
     using boost::asio::ip::tcp;
@@ -241,1045 +241,403 @@ namespace armarx
     \brief parsing datagram and publishing ros messages
     \return error code
     */
-    int SickScanAdapter::loopOnce()
+    int SickScanAdapter::loopOnce(LaserScan& scanData)
     {
-	ARMARX_INFO_S << "myLoop.";
-	static int cnt = 0;
-	diagnostics_.update();
-
-	unsigned char receiveBuffer[65536];
-	int actual_length = 0;
-	static unsigned int iteration_count = 0;
-	bool useBinaryProtocol = this->parser_ptr->getCurrentParamPtr()->getUseBinaryProtocol();
-
-	ros::Time recvTimeStamp = ros::Time::now();  // timestamp incoming package, will be overwritten by get_datagram
-	// tcp packet
-	ros::Time recvTimeStampPush = ros::Time::now();  // timestamp
-
-	/*
-	 * Try to get datagram
-	 *
-	 *
-	 */
-
-
-	int packetsInLoop = 0;
-
-	const int maxNumAllowedPacketsToProcess = 25; // maximum number of packets, which will be processed in this loop.
-
-	int numPacketsProcessed = 0; // count number of processed datagrams
-
-	static bool firstTimeCalled = true;
-	static bool dumpData = false;
-	static int verboseLevel = 0;
-	static bool slamBundle = false;
-	float timeIncrement;
-	static std::string echoForSlam = "";
-	if (firstTimeCalled == true)
-	{
-
-	    /* Dump Binary Protocol */
-	    ros::NodeHandle tmpParam("~");
-	    tmpParam.getParam("slam_echo", echoForSlam);
-	    tmpParam.getParam("slam_bundle", slamBundle);
-	    tmpParam.getParam("verboseLevel", verboseLevel);
-	    firstTimeCalled = false;
-	}
-	do
-	{
-
-	    int result = get_datagram(recvTimeStamp, receiveBuffer, 65536, &actual_length, useBinaryProtocol, &packetsInLoop);
-	    numPacketsProcessed++;
-
-	    ros::Duration dur = recvTimeStampPush - recvTimeStamp;
-
-	    if (result != 0)
-	    {
-		ROS_ERROR("Read Error when getting datagram: %i.", result);
-		diagnostics_.broadcast(getDiagnosticErrorCode(), "Read Error when getting datagram.");
-		return sick_scan::ExitError; // return failure to exit node
-	    }
-	    if (actual_length <= 0)
-	    {
-		return sick_scan::ExitSuccess;
-	    } // return success to continue looping
-
-	    // ----- if requested, skip frames
-	    if (iteration_count++ % (config_.skip + 1) != 0)
-	    {
-		return sick_scan::ExitSuccess;
-	    }
-
-	    //      if (publish_datagram_)
-	    //      {
-	    //      std_msgs::String datagram_msg;
-	    //      datagram_msg.data = std::string(reinterpret_cast<char*>(receiveBuffer));
-	    //      datagram_pub_.publish(datagram_msg);
-	    //      }
-
-
-	    if (verboseLevel > 0)
-	    {
-		dumpDatagramForDebugging(receiveBuffer, actual_length);
-	    }
-
-
-	    bool deviceIsRadar = false;
-
-	    if (this->parser_ptr->getCurrentParamPtr()->getDeviceIsRadar() == true)
-	    {
-		deviceIsRadar = true;
-	    }
-
-	    if (true == deviceIsRadar)
-	    {
-		int errorCode = sick_scan::ExitSuccess;
-#ifndef ROSSIMU
-		SickScanRadarSingleton* radar = SickScanRadarSingleton::getInstance();
-		// parse radar telegram and send pointcloud2-debug messages
-		errorCode = radar->parseDatagram(recvTimeStamp, (unsigned char*) receiveBuffer, actual_length,
-						 useBinaryProtocol);
-#endif
-		return errorCode; // return success to continue looping
-	    }
-
-	    static sick_scan::SickScanImu scanImu(this); // todo remove static
-	    if (scanImu.isImuDatagram((char*) receiveBuffer, actual_length))
-	    {
-		ARMARX_INFO_S << "myLoop1 if.";
-		int errorCode = sick_scan::ExitSuccess;
-		if (scanImu.isImuAckDatagram((char*) receiveBuffer, actual_length))
-		{
-
-		}
-		else
-		{
-		    // parse radar telegram and send pointcloud2-debug messages
-		    errorCode = scanImu.parseDatagram(recvTimeStamp, (unsigned char*) receiveBuffer, actual_length,
-						      useBinaryProtocol);
-
-		}
-		return errorCode; // return success to continue looping
-
-
-	    }
-	    else
-	    {
-		ARMARX_INFO_S << "myLoop1 else.";
-		sensor_msgs::LaserScan msg;
-#ifndef _MSC_VER
-		sick_scan::Encoder EncoderMsg;
-		EncoderMsg.header.stamp = recvTimeStamp + ros::Duration(config_.time_offset);
-		//TODO remove this hardcoded variable
-		bool FireEncoder = false;
-		EncoderMsg.header.frame_id = "Encoder";
-		EncoderMsg.header.seq = numPacketsProcessed;
-#endif
-		msg.header.stamp = recvTimeStamp + ros::Duration(config_.time_offset);
-		double elevationAngleInRad = 0.0;
-		/*
-		 * datagrams are enclosed in <STX> (0x02), <ETX> (0x03) pairs
-		 */
-		char* buffer_pos = (char*) receiveBuffer;
-		char* dstart, *dend;
-		bool dumpDbg = false;
-		bool dataToProcess = true;
-		std::vector<float> vang_vec;
-		vang_vec.clear();
-		dstart = NULL;
-		dend = NULL;
-
-		while (dataToProcess)
-		{
-		    ARMARX_INFO_S << "myLoop2 dataProcess.";
-
-		    const int maxAllowedEchos = 5;
-
-		    uint numValidEchos = 0;
-		    int aiValidEchoIdx[maxAllowedEchos] = {0};
-		    size_t dlength;
-		    int success = -1;
-		    int numEchos = 0;
-		    int echoMask = 0;
-		    bool publishPointCloud = true;
-
-
-		    // Always Parsing Ascii-Encoding of datagram
-		    ARMARX_INFO_S << "myLoop3 ASCII.";
-		    dstart = strchr(buffer_pos, 0x02);
-		    if (dstart != NULL)
-		    {
-			dend = strchr(dstart + 1, 0x03);
-		    }
-		    if ((dstart != NULL) && (dend != NULL))
-		    {
-			dataToProcess = true; // continue parasing
-			dlength = dend - dstart;
-			*dend = '\0';
-			dstart++;
-		    }
-		    else
-		    {
-			dataToProcess = false;
-			break; //
-		    }
-
-		    if (dumpDbg)
-		    {
-			{
-			    static int cnt = 0;
-			    char szFileName[255];
-			    sprintf(szFileName, "/tmp/dump%05d.txt", cnt);
-			    cnt++;
-			}
-		    }
-
-		    // HEADER of data followed by DIST1 ... DIST2 ... DIST3 .... RSSI1 ... RSSI2.... RSSI3...
-
-		    // <frameid>_<sign>00500_DIST[1|2|3]
-		    numEchos = 1;
-		    // numEchos contains number of echos (1..5)
-		    // _msg holds ALL data of all echos
-
-		    ARMARX_INFO_S << "myLoop trying to parse...";
-		    success = parser_ptr->parse_datagram(dstart, dlength, config_, msg, numEchos, echoMask);
-		    publishPointCloud = true; // for MRS1000
-
-		    numValidEchos = 0;
-		    for (int i = 0; i < maxAllowedEchos; i++)
-		    {
-			aiValidEchoIdx[i] = 0;
-		    }
-
-
-
-		    int numOfLayers = parser_ptr->getCurrentParamPtr()->getNumberOfLayers();
-
-		    ARMARX_INFO_S << "numOfLayers: " << numOfLayers;
-
-		    if (success == sick_scan::ExitSuccess)
-		    {
-			ARMARX_INFO_S << "myLoop datagram parsed successfully.";
-
-			bool elevationPreCalculated = false;
-			double elevationAngleDegree = 0.0;
-
-			std::vector<float> rangeTmp = msg.ranges;  // copy all range value
-			std::vector<float> intensityTmp = msg.intensities; // copy all intensity value
-
-			int intensityTmpNum = intensityTmp.size();
-			float* intensityTmpPtr = NULL;
-			if (intensityTmpNum > 0)
-			{
-			    intensityTmpPtr = &intensityTmp[0];
-			}
-
-			// Helpful: https://answers.ros.org/question/191265/pointcloud2-access-data/
-			// https://gist.github.com/yuma-m/b5dcce1b515335c93ce8
-			// Copy to pointcloud
-			int layer = 0;
-			int baseLayer = 0;
-			bool useGivenElevationAngle = false;
-			switch (numOfLayers)
-			{
-			    case 1: // TIM571 etc.
-				baseLayer = 0;
-				break;
-			    case 4:
-
-				baseLayer = -1;
-				if (msg.header.seq == 250)
-				{
-				    layer = -1;
-				}
-				else if (msg.header.seq == 0)
-				{
-				    layer = 0;
-				}
-				else if ((int) msg.header.seq == -250)
-				{
-				    layer = 1;
-				}
-				else if ((int) msg.header.seq == -500)
-				{
-				    layer = 2;
-				}
-				elevationAngleDegree = this->parser_ptr->getCurrentParamPtr()->getElevationDegreeResolution();
-				elevationAngleDegree = elevationAngleDegree / 180.0 * M_PI;
-				// 0.0436332 /*2.5 degrees*/;
-				break;
-			    case 24: // Preparation for MRS6000
-				baseLayer = -1;
-				layer = (msg.header.seq - (-2638)) / 125;
-				layer = (23 - layer) - 1;
-#if 0
-				elevationAngleDegree = this->parser_ptr->getCurrentParamPtr()->getElevationDegreeResolution();
-				elevationAngleDegree = elevationAngleDegree / 180.0 * M_PI;
-#endif
-
-				elevationPreCalculated = true;
-				if (vang_vec.size() > 0)
-				{
-				    useGivenElevationAngle = true;
-				}
-				break;
-			    default:
-				assert(0);
-				break; // unsupported
-
-			}
-
-
-
-
-
-			// XXX  - HIER MEHRERE SCANS publish, falls Mehrzielszenario läuft
-			if (numEchos > 5)
-			{
-			    ARMARX_WARNING_S << "Too many echos";
-			}
-			else
-			{
-
-			    size_t startOffset = 0;
-			    size_t endOffset = 0;
-			    int echoPartNum = msg.ranges.size() / numEchos;
-			    for (int i = 0; i < numEchos; i++)
-			    {
-
-				bool sendMsg = false;
-				if ((echoMask & (1 << i)) & 1 /*for TIM5xx outputChannelFlagId == 1*/)
-				{
-				    aiValidEchoIdx[numValidEchos] = i; // save index
-				    numValidEchos++;
-				    sendMsg = true;
-				}
-				startOffset = i * echoPartNum;
-				endOffset = (i + 1) * echoPartNum;
-
-				msg.ranges.clear();
-				msg.intensities.clear();
-				msg.ranges = std::vector<float>(
-						 rangeTmp.begin() + startOffset,
-						 rangeTmp.begin() + endOffset);
-				// check also for MRS1104
-				if (endOffset <= intensityTmp.size() && (intensityTmp.size() > 0))
-				{
-				    msg.intensities = std::vector<float>(
-							  intensityTmp.begin() + startOffset,
-							  intensityTmp.begin() + endOffset);
-				}
-				else
-				{
-				    msg.intensities.resize(echoPartNum); // fill with zeros
-				}
-				{
-				    // numEchos
-				    char szTmp[255] = {0};
-				    if (this->parser_ptr->getCurrentParamPtr()->getNumberOfLayers() > 1)
-				    {
-					const char* cpFrameId = config_.frame_id.c_str();
-					char szSignName[10] = {0};
-					if ((int) msg.header.seq < 0)
-					{
-					    strcpy(szSignName, "NEG");
-					}
-					else
-					{
-					    strcpy(szSignName, "POS");
-
-					}
-
-					sprintf(szTmp, "%s_%s_%03d_DIST%d", cpFrameId, szSignName, abs((int) msg.header.seq), i + 1);
-				    }
-				    else
-				    {
-					strcpy(szTmp, config_.frame_id.c_str());
-				    }
-
-				    msg.header.frame_id = std::string(szTmp);
-				    // Hector slam can only process ONE valid frame id.
-				    if (echoForSlam.length() > 0)
-				    {
-					if (slamBundle)
-					{
-					    // try to map first echos to horizontal layers.
-					    if (i == 0)
-					    {
-						// first echo
-						msg.header.frame_id = echoForSlam;
-						strcpy(szTmp, echoForSlam.c_str());  //
-						if (elevationAngleInRad != 0.0)
-						{
-						    float cosVal = cos(elevationAngleInRad);
-						    int rangeNum = msg.ranges.size();
-						    for (int j = 0; j < rangeNum; j++)
-						    {
-							msg.ranges[j] *= cosVal;
-						    }
-						}
-					    }
-					}
-
-					if (echoForSlam.compare(szTmp) == 0)
-					{
-					    sendMsg = true;
-					}
-					else
-					{
-					    sendMsg = false;
-					}
-				    }
-
-				}
-#ifndef _MSC_VER
-				if (parser_ptr->getCurrentParamPtr()->getEncoderMode() >= 0 && FireEncoder == true)//
-				{
-				    Encoder_pub.publish(EncoderMsg);
-				}
-				if (numOfLayers > 4)
-				{
-				    sendMsg = false; // too many layers for publish as scan message. Only pointcloud messages will be pub.
-				}
-
-				//for TIM5xx outputChannelFlagId == 1
-				if (sendMsg & 1)  // publish only configured channels - workaround for cfg-bug MRS1104
-				{
-				    //TODO: publish in armarx
-				    //pub_.publish(msg);
-				}
-#else
-				printf("MSG received...");
-#endif
-			    }
-			}
-
-
-			if (publishPointCloud == true)
-			{
-
-
-			    const int numChannels = 4; // x y z i (for intensity)
-
-			    int numTmpLayer = numOfLayers;
-
-
-			    cloud_.header.stamp = recvTimeStamp + ros::Duration(config_.time_offset);
-
-
-			    cloud_.header.frame_id = config_.frame_id;
-			    cloud_.header.seq = 0;
-			    cloud_.height = numTmpLayer * numValidEchos; // due to multi echo multiplied by num. of layers
-			    cloud_.width = msg.ranges.size();
-			    cloud_.is_bigendian = false;
-			    cloud_.is_dense = true;
-			    cloud_.point_step = numChannels * sizeof(float);
-			    cloud_.row_step = cloud_.point_step * cloud_.width;
-			    cloud_.fields.resize(numChannels);
-			    for (int i = 0; i < numChannels; i++)
-			    {
-				std::string channelId[] = {"x", "y", "z", "intensity"};
-				cloud_.fields[i].name = channelId[i];
-				cloud_.fields[i].offset = i * sizeof(float);
-				cloud_.fields[i].count = 1;
-				cloud_.fields[i].datatype = sensor_msgs::PointField::FLOAT32;
-			    }
-
-			    cloud_.data.resize(cloud_.row_step * cloud_.height);
-
-			    unsigned char* cloudDataPtr = &(cloud_.data[0]);
-
-
-			    // prepare lookup for elevation angle table
-
-			    std::vector<float> cosAlphaTable; // Lookup table for cos
-			    std::vector<float> sinAlphaTable; // Lookup table for sin
-			    size_t rangeNum = rangeTmp.size() / numValidEchos;
-			    cosAlphaTable.resize(rangeNum);
-			    sinAlphaTable.resize(rangeNum);
-			    float mirror_factor = 1.0;
-			    float angleShift = 0;
-			    if (this->parser_ptr->getCurrentParamPtr()->getScanMirroredAndShifted())
-			    {
-				//                mirror_factor = -1.0;
-				//                angleShift = +M_PI/2.0; // add 90 deg for NAV3xx-series
-			    }
-
-			    for (size_t iEcho = 0; iEcho < numValidEchos; iEcho++)
-			    {
-
-				float angle = config_.min_ang;
-
-
-				float* cosAlphaTablePtr = &cosAlphaTable[0];
-				float* sinAlphaTablePtr = &sinAlphaTable[0];
-
-				float* vangPtr = NULL;
-				float* rangeTmpPtr = &rangeTmp[0];
-				if (vang_vec.size() > 0)
-				{
-				    vangPtr = &vang_vec[0];
-				}
-				for (size_t i = 0; i < rangeNum; i++)
-				{
-				    enum enum_index_descr
-				    {
-					idx_x,
-					idx_y,
-					idx_z,
-					idx_intensity,
-					idx_num
-				    };
-				    long adroff = i * (numChannels * (int) sizeof(float));
-
-				    adroff += (layer - baseLayer) * cloud_.row_step;
-
-				    adroff += iEcho * cloud_.row_step * numTmpLayer;
-
-				    unsigned char* ptr = cloudDataPtr + adroff;
-				    float* fptr = (float*)(cloudDataPtr + adroff);
-
-				    geometry_msgs::Point32 point;
-				    float range_meter = rangeTmpPtr[iEcho * rangeNum + i];
-				    float phi = angle; // azimuth angle
-				    float alpha = 0.0;  // elevation angle
-
-				    if (useGivenElevationAngle) // FOR MRS6124
-				    {
-					alpha = -vangPtr[i] * deg2rad_const;
-				    }
-				    else
-				    {
-					if (elevationPreCalculated) // FOR MRS6124 without VANGL
-					{
-					    alpha = elevationAngleInRad;
-					}
-					else
-					{
-					    alpha = layer * elevationAngleDegree; // for MRS1104
-					}
-				    }
-
-				    if (iEcho == 0)
-				    {
-					cosAlphaTablePtr[i] = cos(alpha); // for z-value (elevation)
-					sinAlphaTablePtr[i] = sin(alpha);
-				    }
-				    else
-				    {
-					// Just for Debugging: printf("%3d %8.3lf %8.3lf\n", (int)i, cosAlphaTablePtr[i], sinAlphaTablePtr[i]);
-				    }
-				    // Thanks to Sebastian Pütz <spuetz@uos.de> for his hint
-				    float rangeCos = range_meter * cosAlphaTablePtr[i];
-
-				    double phi_used = phi  + angleShift;
-				    //TODO Angle Compensation?
-				    //                                    if (this->angleCompensator != NULL)
-				    //                                    {
-				    //                                        phi_used = angleCompensator->compensateAngleInRadFromRos(phi_used);
-				    //                                    }
-				    fptr[idx_x] = rangeCos * cos(phi_used);  // copy x value in pointcloud
-				    fptr[idx_y] = rangeCos * sin(phi_used);  // copy y value in pointcloud
-				    fptr[idx_z] = range_meter * sinAlphaTablePtr[i] * mirror_factor;// copy z value in pointcloud
-
-				    fptr[idx_intensity] = 0.0;
-				    if (config_.intensity)
-				    {
-					int intensityIndex = aiValidEchoIdx[iEcho] * rangeNum + i;
-					// intensity values available??
-					if (intensityIndex < intensityTmpNum)
-					{
-					    fptr[idx_intensity] = intensityTmpPtr[intensityIndex]; // copy intensity value in pointcloud
-					}
-				    }
-				    angle += msg.angle_increment;
-				}
-				// Publish
-				static int cnt = 0;
-				int layerOff = (layer - baseLayer);
-
-			    }
-			    // if ( (msg.header.seq == 0) || (layerOff == 0)) // FIXEN!!!!
-			    bool shallIFire = false;
-			    if ((msg.header.seq == 0) || (msg.header.seq == 237))
-			    {
-				shallIFire = true;
-			    }
-
-
-			    static int layerCnt = 0;
-			    static int layerSeq[4];
-
-			    if (config_.cloud_output_mode > 0)
-			    {
-
-				layerSeq[layerCnt % 4] = layer;
-				if (layerCnt >= 4)  // mind. erst einmal vier Layer zusammensuchen
-				{
-				    shallIFire = true; // here are at least 4 layers available
-				}
-				else
-				{
-				    shallIFire = false;
-				}
-
-				layerCnt++;
-			    }
-
-			    if (shallIFire) // shall i fire the signal???
-			    {
-#ifdef ROSSIMU
-				static int cnt = 0;
-				cnt++;
-
-				printf("PUBLISH_DATA:\n");
-
-				unsigned char* cloudDataPtr = &(cloud_.data[0]);
-				int w = cloud_.width;
-				int h = cloud_.height;
-
-				int numShots = w * h;
-
-				float* ptr = (float*) cloudDataPtr;
-
-				if (cnt == 25)
-				{
-				    char jpgFileName_tmp[255] = { 0 };
-#if linux
-				    strcpy(jpgFileName_tmp, "./demo/scan.jpg_tmp");
-#else
-				    strcpy(jpgFileName_tmp, "..\\demo\\scan.jpg_tmp");
-#endif
-				    int xic = 400;
-				    int yic = 400;
-				    int w2i = 400;
-				    int h2i = 400;
-				    int hi = h2i * 2 + 1;
-				    int wi = w2i * 2 + 1;
-				    int pixNum = hi * wi;
-				    int numColorChannel = 3;
-				    unsigned char* pixel = (unsigned char*) malloc(numColorChannel * hi * wi);
-				    memset(pixel, 0, numColorChannel * pixNum);
-				    double scaleFac = 50.0;
-
-				    for (int i = 0; i < hi; i++)
-				    {
-					int pixAdr = numColorChannel * (i * wi + xic);
-					pixel[pixAdr] = 0x40;
-					pixel[pixAdr + 1] = 0x40;
-					pixel[pixAdr + 2] = 0x40;
-				    }
-				    for (int i = 0; i < wi; i++)
-				    {
-					int pixAdr = numColorChannel * (yic * wi + i);
-					pixel[pixAdr] = 0x40;
-					pixel[pixAdr + 1] = 0x40;
-					pixel[pixAdr + 2] = 0x40;
-				    }
-
-				    scaleFac *= -1.0;
-				    for (int i = 0; i < numShots; i++)
-				    {
-					double x, y, z, intensity;
-					x = ptr[0];
-					y = ptr[1];
-					z = ptr[2];
-					intensity = ptr[3];
-					ptr += 4;
-					int xi = (x * scaleFac) + xic;
-					int yi = (y * scaleFac) + yic;
-					if ((xi >= 0) && (xi < wi))
-					{
-					    if ((yi >= 0) && (xi < hi))
-					    {
-						// yi shows left (due to neg. scaleFac)
-						// xi shows up (due to neg. scaleFac)
-						int pixAdr = numColorChannel * (xi * wi + yi);
-						int layer = i / w;
-						unsigned char color[3] = {0x00};
-						switch (layer)
-						{
-						    case 0:
-							color[0] = 0xFF;
-							break;
-						    case 1:
-							color[1] = 0xFF;
-							break;
-						    case 2:
-							color[2] = 0xFF;
-							break;
-						    case 3:
-							color[0] = 0xFF;
-							color[1] = 0xFF;
-							break;
-						}
-
-						for (int kk = 0; kk < 3; kk++)
-						{
-						    pixel[pixAdr + kk] = color[kk];
-
-						}
-					    }
-					}
-
-				    }
-
-				    // Write CSV-File
-				    char csvFileNameTmp[255];
-#if linux
-				    strcpy(csvFileNameTmp, "./demo/scan.csv_tmp");
-#endif
-				    FILE* foutCsv = fopen(csvFileNameTmp, "w");
-				    if (foutCsv)
-				    {
-					// ZIEL: fprintf(foutCsv,"timestamp;range;elevation;azimuth;x;y;z;intensity\n");
-					fprintf(foutCsv, "timestamp_sec;timestamp_nanosec;range;azimuth_deg;elevation_deg;x;y;z;intensity\n");
-					unsigned char* cloudDataPtr = &(cloud_.data[0]);
-
-					int numShots = w * h;
-
-					float* ptr = (float*) cloudDataPtr;
-
-
-					long timestamp_sec = cloud_.header.stamp.sec;
-					long timestamp_nanosec = cloud_.header.stamp.nsec;
-					for (int i = 0; i < numShots; i++)
-					{
-					    double x, y, z, intensity;
-					    x = ptr[0];
-					    y = ptr[1];
-					    z = ptr[2];
-					    float range_xy = sqrt(x * x + y * y);
-					    float range_xyz = sqrt(x * x + y * y + z * z);
-					    float elevation = atan2(z, range_xy);
-					    float azimuth = atan2(y, x);
-					    float elevationDeg = elevation * 180.0 / M_PI;
-					    float azimuthDeg = azimuth * 180.0 / M_PI;
-
-					    intensity = ptr[3];
-					    ptr += 4;
-					    fprintf(foutCsv, "%12ld;%12ld;%8.3lf;%8.3lf;%8.3lf;%8.3f;%8.3f;%8.3f;%8.0f\n", timestamp_sec, timestamp_nanosec, range_xyz, azimuthDeg, elevationDeg, x, y, z, intensity);
-					}
-					fclose(foutCsv);
-#ifdef linux
-					rename(csvFileNameTmp, "./demo/scan.csv");
-#else
-					_unlink("..\\demo\\scan.csv");
-					rename(csvFileNameTmp, "..\\demo\\scan.csv");
-#endif
-				    }
-				    else
-				    {
-					ARMARX_INFO_S << "PANIC: Can not open file for writing. Check existience of demo dir. or patch  code.";
-				    }
-				    cnt = 0;
-				}
-
-#else
-				if (config_.cloud_output_mode == 0)
-				{
-				    // standard handling of scans
-				    cloud_pub_.publish(cloud_);
-
-				}
-
-				//                cloud_pub_.publish(cloud_);
-#endif
-			    }
-			}
-		    }
-		    // Start Point
-		    if (dend != NULL)
-		    {
-			buffer_pos = dend + 1;
-		    }
-		} // end of while loop
-	    }
-
-	    // shall we process more data? I.e. are there more packets to process in the input queue???
-
-	}
-	while ((packetsInLoop > 0) && (numPacketsProcessed < maxNumAllowedPacketsToProcess));
-	return sick_scan::ExitSuccess; // return success to continue looping
+        static int cnt = 0;
+
+        unsigned char receiveBuffer[65536];
+        int actual_length = 0;
+        static unsigned int iteration_count = 0;
+        //Always ASCII
+        bool useBinaryProtocol = false;
+
+        ros::Time recvTimeStamp = ros::Time::now();  // timestamp incoming package, will be overwritten by get_datagram
+        // tcp packet
+        ros::Time recvTimeStampPush = ros::Time::now();  // timestamp
+
+        int packetsInLoop = 0;
+        const int maxNumAllowedPacketsToProcess = 25; // maximum number of packets, which will be processed in this loop.
+        int numPacketsProcessed = 0; // count number of processed datagrams
+        do
+        {
+
+            int result = get_datagram(recvTimeStamp, receiveBuffer, 65536, &actual_length, useBinaryProtocol, &packetsInLoop);
+            numPacketsProcessed++;
+
+            ros::Duration dur = recvTimeStampPush - recvTimeStamp;
+
+            if (result != 0)
+            {
+                ARMARX_ERROR_S << "Read Error when getting datagram: " << result;
+                return sick_scan::ExitError; // return failure to exit node
+            }
+            if (actual_length <= 0)
+            {
+                return sick_scan::ExitSuccess;
+            } // return success to continue looping
+
+            // ----- if requested, skip frames
+            if (iteration_count++ % (config_.skip + 1) != 0)
+            {
+                return sick_scan::ExitSuccess;
+            }
+            //msg.header.stamp = recvTimeStamp + ros::Duration(config_.time_offset);
+            //datagrams are enclosed in <STX> (0x02), <ETX> (0x03) pairs
+            char* buffer_pos = (char*) receiveBuffer;
+            char* dstart, *dend;
+            bool dataToProcess = true;
+            std::vector<float> vang_vec;
+            vang_vec.clear();
+            dstart = NULL;
+            dend = NULL;
+
+            while (dataToProcess)
+            {
+                size_t dlength;
+                int success = -1;
+                int numEchos = 1;
+                int echoMask = 0;
+                LaserScannerInfo scanInfo;
+
+                // Always Parsing Ascii-Encoding of datagram
+                dstart = strchr(buffer_pos, 0x02);
+                if (dstart != NULL)
+                {
+                    dend = strchr(dstart + 1, 0x03);
+                }
+                if ((dstart != NULL) && (dend != NULL))
+                {
+                    dataToProcess = true; // continue parsing
+                    dlength = dend - dstart;
+                    *dend = '\0';
+                    dstart++;
+                }
+                else
+                {
+                    dataToProcess = false;
+                    break;
+                }
+
+                // HEADER of data followed by DIST1 ... DIST2 ... DIST3 .... RSSI1 ... RSSI2.... RSSI3...
+                // <frameid>_<sign>00500_DIST[1|2|3]
+                //success = parser_ptr->parse_datagram(dstart, dlength, config_, msg, numEchos, echoMask);
+                success = parseDatagram(dstart, dlength, config_, scanData, scanInfo, numEchos, echoMask, true);
+
+                if (success == sick_scan::ExitSuccess)
+                {
+                    if (numEchos > 5)
+                    {
+                        ARMARX_ERROR_S << "Too many echos";
+                    }
+                    //                            cloud_.header.stamp = recvTimeStamp + ros::Duration(config_.time_offset);
+                    //                            cloud_.header.frame_id = config_.frame_id;
+                    //                            cloud_.header.seq = 0;
+                    //                            cloud_.height = numTmpLayer * numValidEchos; // due to multi echo multiplied by num. of layers
+                    //                            cloud_.width = msg.ranges.size();
+                    //                            cloud_.is_bigendian = false;
+                    //                            cloud_.is_dense = true;
+                    //                            cloud_.point_step = numChannels * sizeof(float);
+                    //                            cloud_.row_step = cloud_.point_step * cloud_.width;
+                    //                            cloud_.fields.resize(numChannels);
+                    //                            for (int i = 0; i < numChannels; i++)
+                    //                            {
+                    //                                std::string channelId[] = {"x", "y", "z", "intensity"};
+                    //                                cloud_.fields[i].name = channelId[i];
+                    //                                cloud_.fields[i].offset = i * sizeof(float);
+                    //                                cloud_.fields[i].count = 1;
+                    //                                cloud_.fields[i].datatype = sensor_msgs::PointField::FLOAT32;
+                    //                            }
+                    cnt++;
+                    if (cnt == 25)
+                    {
+                        ARMARX_INFO_S << "10th measurement: (" << scanData[10].angle << ", " << scanData[10].distance << ")";
+                        cnt = 0;
+                    }
+                }
+                // Start Point
+                if (dend != NULL)
+                {
+                    buffer_pos = dend + 1;
+                }
+            } // end of while loop
+        }
+        while ((packetsInLoop > 0) && (numPacketsProcessed < maxNumAllowedPacketsToProcess));
+        return sick_scan::ExitSuccess; // return success to continue looping
     }
 
-    /*
     //Adapted from sick_generic_parser
-    int SickScanAdapter::parse_datagram(char* datagram, size_t datagram_length, sick_scan::SickScanConfig& config,
-    sensor_msgs::LaserScan& msg, int& numEchos, int& echoMask)
-    {
-    // echoMask introduced to get a workaround for cfg bug using MRS1104
-    ros::NodeHandle tmpParam("~");
-    bool dumpData = false;
-    int verboseLevel = 0;
-    tmpParam.getParam("verboseLevel", verboseLevel);
-
-    int HEADER_FIELDS = 32;
-    char* cur_field;
-    size_t count;
-    int scannerIdx = parser_ptr->lookUpForAllowedScanner(parser_ptr->getScannerType());
-
-    // Reserve sufficient space
-    std::vector<char*> fields;
-    fields.reserve(datagram_length / 2);
-
-    // ----- only for debug output
-    std::vector<char> datagram_copy_vec;
-    datagram_copy_vec.resize(datagram_length + 1); // to avoid using malloc. destructor frees allocated mem.
-    char* datagram_copy = &(datagram_copy_vec[0]);
-
-    if (verboseLevel > 0)
-    {
-    ARMARX_WARNING("Verbose LEVEL activated. Only for DEBUG.");
-    }
-
-    if (verboseLevel > 0)
-    {
-    static int cnt = 0;
-    char szDumpFileName[511] = {0};
-    char szDir[255] = {0};
-    #ifdef _MSC_VER
-    strcpy(szDir, "C:\\temp\\");
-    #else
-    strcpy(szDir, "/tmp/");
-    #endif
-    sprintf(szDumpFileName, "%stmp%06d.bin", szDir, cnt);
-    bool isBinary = parser_ptr->getCurrentParamPtr()->getUseBinaryProtocol();
-    if (isBinary)
-    {
-    FILE* ftmp;
-    ftmp = fopen(szDumpFileName, "wb");
-    if (ftmp != NULL)
-    {
-    fwrite(datagram, datagram_length, 1, ftmp);
-    fclose(ftmp);
-    }
-    }
-    cnt++;
-    }
-    ARMARX_INFO("parse_datagram(): Copying");
-    strncpy(datagram_copy, datagram, datagram_length); // datagram will be changed by strtok
-    datagram_copy[datagram_length] = 0;
-
-    count = 0;
-    cur_field = strtok(datagram, " ");
-
-    while (cur_field != NULL)
-    {
-    fields.push_back(cur_field);
-    cur_field = strtok(NULL, " ");
-    }
-    count = fields.size();
-
-    if (verboseLevel > 0)
-    {
-    static int cnt = 0;
-    char szDumpFileName[511] = {0};
-    char szDir[255] = {0};
-
-    strcpy(szDir, "/tmp/");
-    sprintf(szDumpFileName, "%stmp%06d.txt", szDir, cnt);
-    ARMARX_WARNING("Verbose LEVEL activated. Only for DEBUG.");
-    FILE* ftmp;
-    ftmp = fopen(szDumpFileName, "w");
-    if (ftmp != NULL)
-    {
-    for (uint i = 0; i < count; i++)
-    {
-    fprintf(ftmp, "%3d: %s\n", i, fields[i]);
-    }
-    fclose(ftmp);
-    }
-    cnt++;
-    }
-
-
-    ARMARX_INFO("parse_datagram(): Validate header");
-    // Validate header. Total number of tokens is highly unreliable as this may
-    // change when you change the scanning range or the device name using SOPAS ET
-    // tool. The header remains stable, however.
-    if (count < HEADER_FIELDS)
-    {
-    ARMARX_WARNING(
-    "received less fields than minimum fields (actual: %d, minimum: %d), ignoring scan", (int) count,
-    HEADER_FIELDS);
-    ARMARX_WARNING(
-    "are you using the correct node? (124 --> sick_tim310_1130000m01, > 33 --> sick_tim551_2050001, 580 --> sick_tim310s01, 592 --> sick_tim310)");
-    // ROS_DEBUG("received message was: %s", datagram_copy);
-    return sick_scan::ExitError;
-    }
-
-    if (strcmp(fields[15], "0"))
-    {
-    ARMARX_WARNING("Field 15 of received data is not equal to 0 (%s). Unexpected data, ignoring scan", fields[15]);
-    return sick_scan::ExitError;
-    }
-    if (strcmp(fields[20], "DIST1"))
-    {
-    ARMARX_WARNING("Field 20 of received data is not equal to DIST1i (%s). Unexpected data, ignoring scan", fields[20]);
-    return sick_scan::ExitError;
-    }
-
-    // More in depth checks: check data length and RSSI availability
-    // 25: Number of data (<= 10F)
-    unsigned short int number_of_data = 0;
-    sscanf(fields[25], "%hx", &number_of_data);
-
-    int numOfExpectedShots = parser_ptr->basicParams[scannerIdx].getNumberOfShots();
-    if (number_of_data < 1 || number_of_data > numOfExpectedShots)
-    {
-    ARMARX_WARNING("Data length is outside acceptable range 1-%d (%d). Ignoring scan", numOfExpectedShots, number_of_data);
-    return sick_scan::ExitError;
-    }
-    if (count < HEADER_FIELDS + number_of_data)
-    {
-    ARMARX_WARNING("Less fields than expected for %d data points (%zu). Ignoring scan", number_of_data, count);
-    return sick_scan::ExitError;
-    }
-    ROS_DEBUG("Number of data: %d", number_of_data);
-
-    // Calculate offset of field that contains indicator of whether or not RSSI data is included
-    size_t rssi_idx = 26 + number_of_data;
-    bool rssi = false;
-    if (strcmp(fields[rssi_idx], "RSSI1") == 0)
-    {
-    rssi = true;
-    }
-    unsigned short int number_of_rssi_data = 0;
-    if (rssi)
+    int SickScanAdapter::parseDatagram(char* datagram, size_t datagram_length, sick_scan::SickScanConfig& config,
+                                       LaserScan& scanData, LaserScannerInfo& scanInfo, int& numEchos, int& echoMask, bool updateScannerInfo)
     {
-    sscanf(fields[rssi_idx + 5], "%hx", &number_of_rssi_data);
-
-    // Number of RSSI data should be equal to number of data
-    if (number_of_rssi_data != number_of_data)
-    {
-    ARMARX_WARNING("Number of RSSI data is lower than number of range data (%d vs %d", number_of_data,
-       number_of_rssi_data);
-    return sick_scan::ExitError;
-    }
-
-    // Check if the total length is still appropriate.
-    // RSSI data size = number of RSSI readings + 6 fields describing the data
-    if (count < HEADER_FIELDS + number_of_data + number_of_rssi_data + 6)
-    {
-    ARMARX_WARNING("Less fields than expected for %d data points (%zu). Ignoring scan", number_of_data, count);
-    return sick_scan::ExitError;
+        int HEADER_FIELDS = 32;
+        char* cur_field;
+        size_t count;
+
+        // Reserve sufficient space
+        std::vector<char*> fields;
+        fields.reserve(datagram_length / 2);
+
+        // ----- only for debug output
+        std::vector<char> datagram_copy_vec;
+        datagram_copy_vec.resize(datagram_length + 1); // to avoid using malloc. destructor frees allocated mem.
+        char* datagram_copy = &(datagram_copy_vec[0]);
+
+        ARMARX_INFO_S << "parse_datagram(): Copying";
+        strncpy(datagram_copy, datagram, datagram_length); // datagram will be changed by strtok
+        datagram_copy[datagram_length] = 0;
+
+        count = 0;
+        cur_field = strtok(datagram, " ");
+
+        while (cur_field != NULL)
+        {
+            fields.push_back(cur_field);
+            cur_field = strtok(NULL, " ");
+        }
+        count = fields.size();
+
+        ARMARX_INFO_S << "parse_datagram(): Validate header";
+        // Validate header. Total number of tokens is highly unreliable as this may
+        // change when you change the scanning range or the device name using SOPAS ET
+        // tool. The header remains stable, however.
+        if ((int) count < HEADER_FIELDS)
+        {
+            ARMARX_ERROR_S << "received less fields than minimum fields (actual: " << count
+                           << ", minimum: " << HEADER_FIELDS << "), ignoring scan\n"
+                           << "are you using the correct node? (124 --> sick_tim310_1130000m01, > 33 --> sick_tim551_2050001, 580 --> sick_tim310s01, 592 --> sick_tim310)";
+            return sick_scan::ExitError;
+        }
+
+        if (strcmp(fields[15], "0"))
+        {
+            ARMARX_ERROR_S << "Field 15 of received data is not equal to 0. Unexpected data, ignoring scan";
+            return sick_scan::ExitError;
+        }
+        if (strcmp(fields[20], "DIST1"))
+        {
+            ARMARX_ERROR_S << "Field 20 of received data is not equal to DIST1i. Unexpected data, ignoring scan";
+            return sick_scan::ExitError;
+        }
+
+        // More in depth checks: check data length and RSSI availability
+        // 25: Number of data (<= 10F)
+        unsigned short int number_of_data = 0;
+        sscanf(fields[25], "%hx", &number_of_data);
+
+        //int numOfExpectedShots = parser_ptr->basicParams[scannerIdx].getNumberOfShots();
+        //if (number_of_data < 1 || number_of_data > numOfExpectedShots)
+        //{
+        //    ARMARX_ERROR_S << "Data length is outside acceptable range 1-%d (%d). Ignoring scan";//, numOfExpectedShots, number_of_data);
+        //    return sick_scan::ExitError;
+        //}
+        if ((int) count < HEADER_FIELDS + number_of_data)
+        {
+            ARMARX_ERROR_S << "Less fields than expected for %d data points (%zu). Ignoring scan"; //, number_of_data, count);
+            return sick_scan::ExitError;
+        }
+
+        // Calculate offset of field that contains indicator of whether or not RSSI data is included
+        size_t rssi_idx = 26 + number_of_data;
+        bool rssi = false;
+        if (strcmp(fields[rssi_idx], "RSSI1") == 0)
+        {
+            rssi = true;
+        }
+        unsigned short int number_of_rssi_data = 0;
+        if (rssi)
+        {
+            sscanf(fields[rssi_idx + 5], "%hx", &number_of_rssi_data);
+
+            // Number of RSSI data should be equal to number of data
+            if (number_of_rssi_data != number_of_data)
+            {
+                //      ARMARX_ERROR("Number of RSSI data is lower than number of range data (%d vs %d", number_of_data,
+                //               number_of_rssi_data);
+                return sick_scan::ExitError;
+            }
+
+            // Check if the total length is still appropriate.
+            // RSSI data size = number of RSSI readings + 6 fields describing the data
+            if ((int) count < HEADER_FIELDS + number_of_data + number_of_rssi_data + 6)
+            {
+                //      ARMARX_ERROR("Less fields than expected for %d data points (%zu). Ignoring scan", number_of_data, count);
+                return sick_scan::ExitError;
+            }
+
+            if (strcmp(fields[rssi_idx], "RSSI1"))
+            {
+                //      ARMARX_ERROR("Field %zu of received data is not equal to RSSI1 (%s). Unexpected data, ignoring scan", rssi_idx + 1,
+                //               fields[rssi_idx + 1]);
+            }
+        }
+
+        ARMARX_INFO_S << "parse_datagram(): Checks complete";
+
+        // ----- read fields into msg
+        //msg.header.frame_id = config.frame_id;
+        // evtl. debug stream benutzen
+        // ROS_DEBUG("publishing with frame_id %s", config.frame_id.c_str());
+
+        ros::Time start_time = ros::Time::now(); // will be adjusted in the end
+
+        // <STX> (\x02)
+        // 0: Type of command (SN)
+        // 1: Command (LMDscandata)
+        // 2: Firmware version number (1)
+        // 3: Device number (1)
+        // 4: Serial number (eg. B96518)
+        // 5 + 6: Device Status (0 0 = ok, 0 1 = error)
+        // 7: Telegram counter (eg. 99)
+        // 8: Scan counter (eg. 9A)
+        // 9: Time since startup (eg. 13C8E59)
+        // 10: Time of transmission (eg. 13C9CBE)
+        // 11 + 12: Input status (0 0)
+        // 13 + 14: Output status (8 0)
+        // 15: Reserved Byte A (0)
+        // 16: Scanning Frequency (5DC)
+        unsigned short scanning_freq = -1;
+        sscanf(fields[16], "%hx", &scanning_freq);
+        //  msg.scan_time = 1.0 / (scanning_freq / 100.0);
+
+        // 17: Measurement Frequency (36)
+        unsigned short measurement_freq = -1;
+        sscanf(fields[17], "%hx", &measurement_freq);
+        //  msg.time_increment = 1.0 / (measurement_freq * 100.0);
+
+        // 18: Number of encoders (0)
+        // 19: Number of 16 bit channels (1)
+        // 20: Measured data contents (DIST1)
+        // 21: Scaling factor (3F800000)
+        // ignored for now (is always 1.0):
+        // 22: Scaling offset (00000000) -- always 0
+        // 23: Starting angle (FFF92230)
+        if (updateScannerInfo)
+        {
+            uint starting_angle = (uint) - 1;
+            sscanf(fields[23], "%x", &starting_angle);
+            scanInfo.minAngle = (starting_angle / 10000.0) / 180.0 * M_PI - M_PI / 2;
+            // ROS_DEBUG("starting_angle: %d, angle_min: %f", starting_angle, msg.angle_min);
+
+            // 24: Angular step width (2710)
+            unsigned short angular_step_width = -1;
+            sscanf(fields[24], "%hx", &angular_step_width);
+            scanInfo.stepSize = (angular_step_width / 10000.0) / 180.0 * M_PI;
+            scanInfo.maxAngle = scanInfo.minAngle + (number_of_data - 1) * scanInfo.stepSize;
+        }
+
+        // 25: Number of data (<= 10F)
+        // This is already determined above in number_of_data
+        //int index_min = 0;
+
+        ARMARX_INFO_S << "parse_datagram(): Parsing";
+        //param_ptr->checkForDistAndRSSI(fields, number_of_data, distNum, rssiNum, msg.ranges, msg.intensities, echoMask);
+
+        int distNum = 0;
+        int rssiNum = 0;
+        int baseOffset = 20;
+
+        echoMask = 0;
+        // More in depth checks: check data length and RSSI availability
+        // 25: Number of data (<= 10F)
+        unsigned short int curr_number_of_data = 0;
+        if (strstr(fields[baseOffset], "DIST") != fields[baseOffset]) // First initial check
+        {
+            //      ARMARX_ERROR("Field 20 of received data does not start with DIST (is: %s). Unexpected data, ignoring scan",
+            //           fields[20]);
+            return sick_scan::ExitError;
+        }
+
+        //Read either intensity or distance data, regarding what type is given in the datagram
+        std::vector<float> distVal, intensityVal;
+        for (int offset = 20; offset < (int) fields.size();)
+        {
+            bool distFnd = false;
+            bool rssiFnd = false;
+            if (strlen(fields[offset]) == 5)
+            {
+                if (strstr(fields[offset], "DIST") == fields[offset])
+                {
+                    distFnd = true;
+                    distNum++;
+                    int distId = -1;
+                    if (1 == sscanf(fields[offset], "DIST%d", &distId))
+                    {
+                        echoMask |= (1 << (distId - 1)); // set bit regarding to id
+                    }
+                }
+                else if (strstr(fields[offset], "RSSI") == fields[offset])
+                {
+                    rssiNum++;
+                    rssiFnd = true;
+                }
+            }
+            if (rssiFnd || distFnd)
+            {
+                offset += 5;
+                if (offset >= (int) fields.size())
+                {
+                    ARMARX_ERROR_S << "Missing RSSI or DIST data";
+                    return sick_scan::ExitError;
+                }
+                curr_number_of_data = 0;
+                sscanf(fields[offset], "%hx", &curr_number_of_data);
+                if (curr_number_of_data != number_of_data)
+                {
+                    ARMARX_ERROR_S << "number of dist or rssi values mismatching.";
+                    return sick_scan::ExitError;
+                }
+                offset++;
+                // Here is the first value
+                for (int i = 0; i < curr_number_of_data; i++)
+                {
+                    if (distFnd)
+                    {
+                        unsigned short iRange;
+                        sscanf(fields[offset + i], "%hx", &iRange);
+                        float range = iRange / 1000.0;
+                        distVal.push_back(range);
+                    }
+                    else
+                    {
+                        unsigned short iRSSI;
+                        sscanf(fields[offset + i], "%hx", &iRSSI);
+                        intensityVal.push_back((float) iRSSI);
+                    }
+                }
+                offset += number_of_data;
+            }
+            else
+            {
+                offset++; // necessary????
+            }
+        }
+        numEchos = distNum;
+
+        ARMARX_INFO_S << "numDistanceVals: " << distNum << ", numIntensityVals: " << rssiNum;
+        //TODO: Write ScanSteps with intensity
+        scanData.reserve(distVal.size());
+        for (int i = 0; i < (int) distVal.size(); i++)
+        {
+            LaserScanStep step;
+            step.angle = i * scanInfo.stepSize;
+            step.distance = distVal[i];
+            scanData.push_back(step);
+        }
+
+        // 26 + n: RSSI data included
+        // IF RSSI not included:
+        //   26 + n + 1 .. 26 + n + 3 = unknown (but seems to be [0, 1, B] always)
+        //   26 + n + 4 .. count - 4 = device label
+        //   count - 3 .. count - 1 = unknown (but seems to be 0 always)
+        //   <ETX> (\x03)
+
+        //  msg.range_min = override_range_min_;
+        //  msg.range_max = override_range_max_;
+
+        ARMARX_INFO_S << "parse_datagram(): Time check";
+        return sick_scan::ExitSuccess;
     }
 
-    if (strcmp(fields[rssi_idx], "RSSI1"))
-    {
-    ARMARX_WARNING("Field %zu of received data is not equal to RSSI1 (%s). Unexpected data, ignoring scan", rssi_idx + 1,
-       fields[rssi_idx + 1]);
-    }
-    }
-
-    ARMARX_INFO("parse_datagram(): Checks complete");
-
-    // ----- read fields into msg
-    msg.header.frame_id = config.frame_id;
-    // evtl. debug stream benutzen
-    // ROS_DEBUG("publishing with frame_id %s", config.frame_id.c_str());
-
-    ros::Time start_time = ros::Time::now(); // will be adjusted in the end
-
-    // <STX> (\x02)
-    // 0: Type of command (SN)
-    // 1: Command (LMDscandata)
-    // 2: Firmware version number (1)
-    // 3: Device number (1)
-    // 4: Serial number (eg. B96518)
-    // 5 + 6: Device Status (0 0 = ok, 0 1 = error)
-    // 7: Telegram counter (eg. 99)
-    // 8: Scan counter (eg. 9A)
-    // 9: Time since startup (eg. 13C8E59)
-    // 10: Time of transmission (eg. 13C9CBE)
-    // 11 + 12: Input status (0 0)
-    // 13 + 14: Output status (8 0)
-    // 15: Reserved Byte A (0)
-    // 16: Scanning Frequency (5DC)
-    unsigned short scanning_freq = -1;
-    sscanf(fields[16], "%hx", &scanning_freq);
-    msg.scan_time = 1.0 / (scanning_freq / 100.0);
-    // ROS_DEBUG("hex: %s, scanning_freq: %d, scan_time: %f", fields[16], scanning_freq, msg.scan_time);
-
-    // 17: Measurement Frequency (36)
-    unsigned short measurement_freq = -1;
-    sscanf(fields[17], "%hx", &measurement_freq);
-    msg.time_increment = 1.0 / (measurement_freq * 100.0);
-    // ROS_DEBUG("measurement_freq: %d, time_increment: %f", measurement_freq, msg.time_increment);
-
-    // 18: Number of encoders (0)
-    // 19: Number of 16 bit channels (1)
-    // 20: Measured data contents (DIST1)
-
-    // 21: Scaling factor (3F800000)
-    // ignored for now (is always 1.0):
-    //      unsigned int scaling_factor_int = -1;
-    //      sscanf(fields[21], "%x", &scaling_factor_int);
-    //
-    //      float scaling_factor = reinterpret_cast<float&>(scaling_factor_int);
-    //      // ROS_DEBUG("hex: %s, scaling_factor_int: %d, scaling_factor: %f", fields[21], scaling_factor_int, scaling_factor);
-
-    // 22: Scaling offset (00000000) -- always 0
-    // 23: Starting angle (FFF92230)
-    int starting_angle = -1;
-    sscanf(fields[23], "%x", &starting_angle);
-    msg.angle_min = (starting_angle / 10000.0) / 180.0 * M_PI - M_PI / 2;
-    // ROS_DEBUG("starting_angle: %d, angle_min: %f", starting_angle, msg.angle_min);
-
-    // 24: Angular step width (2710)
-    unsigned short angular_step_width = -1;
-    sscanf(fields[24], "%hx", &angular_step_width);
-    msg.angle_increment = (angular_step_width / 10000.0) / 180.0 * M_PI;
-    msg.angle_max = msg.angle_min + (number_of_data - 1) * msg.angle_increment;
-
-    // 25: Number of data (<= 10F)
-    // This is already determined above in number_of_data
-    int index_min = 0;
-
-    ARMARX_INFO("parse_datagram(): Parsing");
-    #if 1  // neuer Ansatz
-    int distNum = 0;
-    int rssiNum = 0;
-
-    param_ptr->checkForDistAndRSSI(fields, number_of_data, distNum, rssiNum, msg.ranges, msg.intensities, echoMask);
-    if (config.intensity)
-    {
-    if (rssiNum > 0)
-    {
-
-    }
-    else
-    {
-    ARMARX_WARNING("Intensity parameter is enabled, but the scanner is not configured to send RSSI values! "
-       "Please read the section 'Enabling intensity (RSSI) output' here: http://wiki.ros.org/sick_tim.");
-    }
-    }
-    numEchos = distNum;
-    #endif
-    // 26 + n: RSSI data included
-    // IF RSSI not included:
-    //   26 + n + 1 .. 26 + n + 3 = unknown (but seems to be [0, 1, B] always)
-    //   26 + n + 4 .. count - 4 = device label
-    //   count - 3 .. count - 1 = unknown (but seems to be 0 always)
-    //   <ETX> (\x03)
-
-    msg.range_min = override_range_min_;
-    msg.range_max = override_range_max_;
-
-    ARMARX_INFO("parse_datagram(): Time check");
-    float expected_time_increment =
-    fabs(param_ptr->getCurrentParamPtr()->getNumberOfLayers() * msg.scan_time * msg.angle_increment / (2.0 * M_PI));//If the direction of rotation is reversed, i.e. negative angle increment, a negative scan time results. This does not makes sense, therefore the absolute value is calculated.
-    if (fabs(expected_time_increment - msg.time_increment) > 0.00001)
-    {
-    ARMARX_WARNING("The time_increment, scan_time and angle_increment values reported by the scanner are inconsistent! "
-       "Expected time_increment: %.9f, reported time_increment: %.9f. "
-       "Perhaps you should set the parameter time_increment to the expected value. This message will print every 60 seconds.",
-       expected_time_increment, msg.time_increment);
-    }
-    return sick_scan::ExitSuccess;
-    }
-    */
 
     void SickScanAdapter::disconnectFunction()
     {
@@ -1288,26 +646,26 @@ namespace armarx
 
     void SickScanAdapter::disconnectFunctionS(void* obj)
     {
-	if (obj != NULL)
-	{
-	    ((SickScanAdapter*)(obj))->disconnectFunction();
-	}
+        if (obj != NULL)
+        {
+            ((SickScanAdapter*)(obj))->disconnectFunction();
+        }
     }
 
     void SickScanAdapter::readCallbackFunctionS(void* obj, UINT8* buffer, UINT32& numOfBytes)
     {
-	((SickScanAdapter*) obj)->readCallbackFunction(buffer, numOfBytes);
+        ((SickScanAdapter*) obj)->readCallbackFunction(buffer, numOfBytes);
     }
 
 
     void SickScanAdapter::setReplyMode(int _mode)
     {
-	m_replyMode = _mode;
+        m_replyMode = _mode;
     }
 
     int SickScanAdapter::getReplyMode()
     {
-	return (m_replyMode);
+        return (m_replyMode);
     }
 
     /*!
@@ -1317,7 +675,7 @@ namespace armarx
     */
     void SickScanAdapter::setEmulSensor(bool _emulFlag)
     {
-	m_emulSensor = _emulFlag;
+        m_emulSensor = _emulFlag;
     }
 
     /*!
@@ -1327,7 +685,7 @@ namespace armarx
     */
     bool SickScanAdapter::getEmulSensor()
     {
-	return (m_emulSensor);
+        return (m_emulSensor);
     }
 
     //
@@ -1339,173 +697,173 @@ namespace armarx
     //
     SopasEventMessage SickScanAdapter::findFrameInReceiveBuffer()
     {
-	UINT32 frameLen = 0;
-	UINT32 i;
-
-	// Depends on protocol...
-	if (getProtocolType() == CoLa_A)
-	{
-	    //
-	    // COLA-A
-	    //
-	    // Must start with STX (0x02)
-	    if (m_receiveBuffer[0] != 0x02)
-	    {
-		// Look for starting STX (0x02)
-		for (i = 1; i < m_numberOfBytesInReceiveBuffer; i++)
-		{
-		    if (m_receiveBuffer[i] == 0x02)
-		    {
-			break;
-		    }
-		}
-
-		// Found beginning of frame?
-		if (i >= m_numberOfBytesInReceiveBuffer)
-		{
-		    // No start found, everything can be discarded
-		    m_numberOfBytesInReceiveBuffer = 0; // Invalidate buffer
-		    return SopasEventMessage(); // No frame found
-		}
-
-		// Move frame start to index 0
-		UINT32 newLen = m_numberOfBytesInReceiveBuffer - i;
-		memmove(&(m_receiveBuffer[0]), &(m_receiveBuffer[i]), newLen);
-		m_numberOfBytesInReceiveBuffer = newLen;
-	    }
-
-	    // Look for ending ETX (0x03)
-	    for (i = 1; i < m_numberOfBytesInReceiveBuffer; i++)
-	    {
-		if (m_receiveBuffer[i] == 0x03)
-		{
-		    break;
-		}
-	    }
-
-	    // Found end?
-	    if (i >= m_numberOfBytesInReceiveBuffer)
-	    {
-		// No end marker found, so it's not a complete frame (yet)
-		return SopasEventMessage(); // No frame found
-	    }
-
-	    // Calculate frame length in byte
-	    frameLen = i + 1;
-
-	    return SopasEventMessage(m_receiveBuffer, CoLa_A, frameLen);
-	}
-	else if (getProtocolType() == CoLa_B)
-	{
-	    UINT32 magicWord;
-	    UINT32 payloadlength;
-
-	    if (m_numberOfBytesInReceiveBuffer < 4)
-	    {
-		return SopasEventMessage();
-	    }
-	    UINT16 pos = 0;
-	    magicWord = colab::getIntegerFromBuffer<UINT32>(m_receiveBuffer, pos);
-	    if (magicWord != 0x02020202)
-	    {
-		// Look for starting STX (0x02020202)
-		for (i = 1; i <= m_numberOfBytesInReceiveBuffer - 4; i++)
-		{
-		    pos = i; // this is needed, as the position value is updated by getIntegerFromBuffer
-		    magicWord = colab::getIntegerFromBuffer<UINT32>(m_receiveBuffer, pos);
-		    if (magicWord == 0x02020202)
-		    {
-			// found magic word
-			break;
-		    }
-		}
-
-		// Found beginning of frame?
-		if (i > m_numberOfBytesInReceiveBuffer - 4)
-		{
-		    // No start found, everything can be discarded
-		    m_numberOfBytesInReceiveBuffer = 0; // Invalidate buffer
-		    return SopasEventMessage(); // No frame found
-		}
-		else
-		{
-		    // Move frame start to index
-		    UINT32 bytesToMove = m_numberOfBytesInReceiveBuffer - i;
-		    memmove(&(m_receiveBuffer[0]), &(m_receiveBuffer[i]), bytesToMove); // payload+magic+length+s+checksum
-		    m_numberOfBytesInReceiveBuffer = bytesToMove;
-		}
-	    }
-
-	    // Pruefe Laenge des Pufferinhalts
-	    if (m_numberOfBytesInReceiveBuffer < 9)
-	    {
-		// Es sind nicht genug Daten fuer einen Frame
-		printInfoMessage("SickScanCommonNw::findFrameInReceiveBuffer: Frame cannot be decoded yet, only " +
-				 ::toString(m_numberOfBytesInReceiveBuffer) + " bytes in the buffer.", m_beVerbose);
-		return SopasEventMessage();
-	    }
-
-	    // Read length of payload
-	    pos = 4;
-	    payloadlength = colab::getIntegerFromBuffer<UINT32>(m_receiveBuffer, pos);
-	    printInfoMessage(
-		"SickScanCommonNw::findFrameInReceiveBuffer: Decoded payload length is " + ::toString(payloadlength) +
-		" bytes.", m_beVerbose);
-
-	    // Ist die Datenlaenge plausibel und wuede in den Puffer passen?
-	    if (payloadlength > (sizeof(m_receiveBuffer) - 9))
-	    {
-		// magic word + length + checksum = 9
-		printWarning(
-		    "SickScanCommonNw::findFrameInReceiveBuffer: Frame too big for receive buffer. Frame discarded with length:"
-		    + ::toString(payloadlength) + ".");
-		m_numberOfBytesInReceiveBuffer = 0;
-		return SopasEventMessage();
-	    }
-	    if ((payloadlength + 9) > m_numberOfBytesInReceiveBuffer)
-	    {
-		// magic word + length + s + checksum = 10
-		printInfoMessage(
-		    "SickScanCommonNw::findFrameInReceiveBuffer: Frame not complete yet. Waiting for the rest of it (" +
-		    ::toString(payloadlength + 9 - m_numberOfBytesInReceiveBuffer) + " bytes missing).", m_beVerbose);
-		return SopasEventMessage(); // frame not complete
-	    }
-
-	    // Calculate the total frame length in bytes: Len = Frame (9 bytes) + Payload
-	    frameLen = payloadlength + 9;
-
-	    //
-	    // test checksum of payload
-	    //
-	    UINT8 temp = 0;
-	    UINT8 temp_xor = 0;
-	    UINT8 checkSum;
-
-	    // Read original checksum
-	    pos = frameLen - 1;
-	    checkSum = colab::getIntegerFromBuffer<UINT8>(m_receiveBuffer, pos);
-
-	    // Erzeuge die Pruefsumme zum Vergleich
-	    for (UINT16 i = 8; i < (frameLen - 1); i++)
-	    {
-		pos = i;
-		temp = colab::getIntegerFromBuffer<UINT8>(m_receiveBuffer, pos);
-		temp_xor = temp_xor ^ temp;
-	    }
-
-	    // Vergleiche die Pruefsummen
-	    if (temp_xor != checkSum)
-	    {
-		printWarning("SickScanCommonNw::findFrameInReceiveBuffer: Wrong checksum, Frame discarded.");
-		m_numberOfBytesInReceiveBuffer = 0;
-		return SopasEventMessage();
-	    }
-
-	    return SopasEventMessage(m_receiveBuffer, CoLa_B, frameLen);
-	}
-
-	// Return empty frame
-	return SopasEventMessage();
+        UINT32 frameLen = 0;
+        UINT32 i;
+
+        // Depends on protocol...
+        if (getProtocolType() == CoLa_A)
+        {
+            //
+            // COLA-A
+            //
+            // Must start with STX (0x02)
+            if (m_receiveBuffer[0] != 0x02)
+            {
+                // Look for starting STX (0x02)
+                for (i = 1; i < m_numberOfBytesInReceiveBuffer; i++)
+                {
+                    if (m_receiveBuffer[i] == 0x02)
+                    {
+                        break;
+                    }
+                }
+
+                // Found beginning of frame?
+                if (i >= m_numberOfBytesInReceiveBuffer)
+                {
+                    // No start found, everything can be discarded
+                    m_numberOfBytesInReceiveBuffer = 0; // Invalidate buffer
+                    return SopasEventMessage(); // No frame found
+                }
+
+                // Move frame start to index 0
+                UINT32 newLen = m_numberOfBytesInReceiveBuffer - i;
+                memmove(&(m_receiveBuffer[0]), &(m_receiveBuffer[i]), newLen);
+                m_numberOfBytesInReceiveBuffer = newLen;
+            }
+
+            // Look for ending ETX (0x03)
+            for (i = 1; i < m_numberOfBytesInReceiveBuffer; i++)
+            {
+                if (m_receiveBuffer[i] == 0x03)
+                {
+                    break;
+                }
+            }
+
+            // Found end?
+            if (i >= m_numberOfBytesInReceiveBuffer)
+            {
+                // No end marker found, so it's not a complete frame (yet)
+                return SopasEventMessage(); // No frame found
+            }
+
+            // Calculate frame length in byte
+            frameLen = i + 1;
+
+            return SopasEventMessage(m_receiveBuffer, CoLa_A, frameLen);
+        }
+        else if (getProtocolType() == CoLa_B)
+        {
+            UINT32 magicWord;
+            UINT32 payloadlength;
+
+            if (m_numberOfBytesInReceiveBuffer < 4)
+            {
+                return SopasEventMessage();
+            }
+            UINT16 pos = 0;
+            magicWord = colab::getIntegerFromBuffer<UINT32>(m_receiveBuffer, pos);
+            if (magicWord != 0x02020202)
+            {
+                // Look for starting STX (0x02020202)
+                for (i = 1; i <= m_numberOfBytesInReceiveBuffer - 4; i++)
+                {
+                    pos = i; // this is needed, as the position value is updated by getIntegerFromBuffer
+                    magicWord = colab::getIntegerFromBuffer<UINT32>(m_receiveBuffer, pos);
+                    if (magicWord == 0x02020202)
+                    {
+                        // found magic word
+                        break;
+                    }
+                }
+
+                // Found beginning of frame?
+                if (i > m_numberOfBytesInReceiveBuffer - 4)
+                {
+                    // No start found, everything can be discarded
+                    m_numberOfBytesInReceiveBuffer = 0; // Invalidate buffer
+                    return SopasEventMessage(); // No frame found
+                }
+                else
+                {
+                    // Move frame start to index
+                    UINT32 bytesToMove = m_numberOfBytesInReceiveBuffer - i;
+                    memmove(&(m_receiveBuffer[0]), &(m_receiveBuffer[i]), bytesToMove); // payload+magic+length+s+checksum
+                    m_numberOfBytesInReceiveBuffer = bytesToMove;
+                }
+            }
+
+            // Pruefe Laenge des Pufferinhalts
+            if (m_numberOfBytesInReceiveBuffer < 9)
+            {
+                // Es sind nicht genug Daten fuer einen Frame
+                printInfoMessage("SickScanCommonNw::findFrameInReceiveBuffer: Frame cannot be decoded yet, only " +
+                                 ::toString(m_numberOfBytesInReceiveBuffer) + " bytes in the buffer.", m_beVerbose);
+                return SopasEventMessage();
+            }
+
+            // Read length of payload
+            pos = 4;
+            payloadlength = colab::getIntegerFromBuffer<UINT32>(m_receiveBuffer, pos);
+            printInfoMessage(
+                "SickScanCommonNw::findFrameInReceiveBuffer: Decoded payload length is " + ::toString(payloadlength) +
+                " bytes.", m_beVerbose);
+
+            // Ist die Datenlaenge plausibel und wuede in den Puffer passen?
+            if (payloadlength > (sizeof(m_receiveBuffer) - 9))
+            {
+                // magic word + length + checksum = 9
+                printWarning(
+                    "SickScanCommonNw::findFrameInReceiveBuffer: Frame too big for receive buffer. Frame discarded with length:"
+                    + ::toString(payloadlength) + ".");
+                m_numberOfBytesInReceiveBuffer = 0;
+                return SopasEventMessage();
+            }
+            if ((payloadlength + 9) > m_numberOfBytesInReceiveBuffer)
+            {
+                // magic word + length + s + checksum = 10
+                printInfoMessage(
+                    "SickScanCommonNw::findFrameInReceiveBuffer: Frame not complete yet. Waiting for the rest of it (" +
+                    ::toString(payloadlength + 9 - m_numberOfBytesInReceiveBuffer) + " bytes missing).", m_beVerbose);
+                return SopasEventMessage(); // frame not complete
+            }
+
+            // Calculate the total frame length in bytes: Len = Frame (9 bytes) + Payload
+            frameLen = payloadlength + 9;
+
+            //
+            // test checksum of payload
+            //
+            UINT8 temp = 0;
+            UINT8 temp_xor = 0;
+            UINT8 checkSum;
+
+            // Read original checksum
+            pos = frameLen - 1;
+            checkSum = colab::getIntegerFromBuffer<UINT8>(m_receiveBuffer, pos);
+
+            // Erzeuge die Pruefsumme zum Vergleich
+            for (UINT16 i = 8; i < (frameLen - 1); i++)
+            {
+                pos = i;
+                temp = colab::getIntegerFromBuffer<UINT8>(m_receiveBuffer, pos);
+                temp_xor = temp_xor ^ temp;
+            }
+
+            // Vergleiche die Pruefsummen
+            if (temp_xor != checkSum)
+            {
+                printWarning("SickScanCommonNw::findFrameInReceiveBuffer: Wrong checksum, Frame discarded.");
+                m_numberOfBytesInReceiveBuffer = 0;
+                return SopasEventMessage();
+            }
+
+            return SopasEventMessage(m_receiveBuffer, CoLa_B, frameLen);
+        }
+
+        // Return empty frame
+        return SopasEventMessage();
     }
 
 
@@ -1517,195 +875,190 @@ namespace armarx
     void SickScanAdapter::processFrame(ros::Time timeStamp, SopasEventMessage& frame)
     {
 
-	if (getProtocolType() == CoLa_A)
-	{
-	    printInfoMessage(
-		"SickScanCommonNw::processFrame: Calling processFrame_CoLa_A() with " + ::toString(frame.size()) + " bytes.",
-		m_beVerbose);
-	    // processFrame_CoLa_A(frame);
-	}
-	else if (getProtocolType() == CoLa_B)
-	{
-	    printInfoMessage(
-		"SickScanCommonNw::processFrame: Calling processFrame_CoLa_B() with " + ::toString(frame.size()) + " bytes.",
-		m_beVerbose);
-	    // processFrame_CoLa_B(frame);
-	}
-
-	// Push frame to recvQueue
-
-	DatagramWithTimeStamp dataGramWidthTimeStamp(timeStamp, std::vector<unsigned char>(frame.getRawData(),
-		frame.getRawData() +
-		frame.size()));
-	// recvQueue.push(std::vector<unsigned char>(frame.getRawData(), frame.getRawData() + frame.size()));
-	recvQueue.push(dataGramWidthTimeStamp);
+        if (getProtocolType() == CoLa_A)
+        {
+            printInfoMessage(
+                "SickScanCommonNw::processFrame: Calling processFrame_CoLa_A() with " + ::toString(frame.size()) + " bytes.",
+                m_beVerbose);
+            // processFrame_CoLa_A(frame);
+        }
+        else if (getProtocolType() == CoLa_B)
+        {
+            printInfoMessage(
+                "SickScanCommonNw::processFrame: Calling processFrame_CoLa_B() with " + ::toString(frame.size()) + " bytes.",
+                m_beVerbose);
+            // processFrame_CoLa_B(frame);
+        }
+
+        // Push frame to recvQueue
+
+        DatagramWithTimeStamp dataGramWidthTimeStamp(timeStamp, std::vector<unsigned char>(frame.getRawData(),
+                frame.getRawData() +
+                frame.size()));
+        // recvQueue.push(std::vector<unsigned char>(frame.getRawData(), frame.getRawData() + frame.size()));
+        recvQueue.push(dataGramWidthTimeStamp);
     }
 
     void SickScanAdapter::readCallbackFunction(UINT8* buffer, UINT32& numOfBytes)
     {
-	ros::Time rcvTimeStamp = ros::Time::now(); // stamp received datagram
-	bool beVerboseHere = false;
-	printInfoMessage(
-	    "SickScanCommonNw::readCallbackFunction(): Called with " + toString(numOfBytes) + " available bytes.",
-	    beVerboseHere);
-
-	ScopedLock lock(&m_receiveDataMutex); // Mutex for access to the input buffer
-	UINT32 remainingSpace = sizeof(m_receiveBuffer) - m_numberOfBytesInReceiveBuffer;
-	UINT32 bytesToBeTransferred = numOfBytes;
-	if (remainingSpace < numOfBytes)
-	{
-	    bytesToBeTransferred = remainingSpace;
-	    // printWarning("SickScanCommonNw::readCallbackFunction(): Input buffer space is to small, transferring only " +
-	    //              ::toString(bytesToBeTransferred) + " of " + ::toString(numOfBytes) + " bytes.");
-	}
-	else
-	{
-	    // printInfoMessage("SickScanCommonNw::readCallbackFunction(): Transferring " + ::toString(bytesToBeTransferred) +
-	    //                   " bytes from TCP to input buffer.", beVerboseHere);
-	}
-
-	if (bytesToBeTransferred > 0)
-	{
-	    // Data can be transferred into our input buffer
-	    memcpy(&(m_receiveBuffer[m_numberOfBytesInReceiveBuffer]), buffer, bytesToBeTransferred);
-	    m_numberOfBytesInReceiveBuffer += bytesToBeTransferred;
-
-	    UINT32 size = 0;
-
-	    while (1)
-	    {
-		// Now work on the input buffer until all received datasets are processed
-		SopasEventMessage frame = findFrameInReceiveBuffer();
-
-		size = frame.size();
-		if (size == 0)
-		{
-		    // Framesize = 0: There is no valid frame in the buffer. The buffer is either empty or the frame
-		    // is incomplete, so leave the loop
-		    printInfoMessage("SickScanCommonNw::readCallbackFunction(): No complete frame in input buffer, we are done.",
-				     beVerboseHere);
-
-		    // Leave the loop
-		    break;
-		}
-		else
-		{
-		    // A frame was found in the buffer, so process it now.
-		    printInfoMessage(
-			"SickScanCommonNw::readCallbackFunction(): Processing a frame of length " + ::toString(frame.size()) +
-			" bytes.", beVerboseHere);
-		    processFrame(rcvTimeStamp, frame);
-		    UINT32 bytesToMove = m_numberOfBytesInReceiveBuffer - size;
-		    memmove(&(m_receiveBuffer[0]), &(m_receiveBuffer[size]), bytesToMove); // payload+magic+length+s+checksum
-		    m_numberOfBytesInReceiveBuffer = bytesToMove;
-
-		}
-	    }
-	}
-	else
-	{
-	    // There was input data from the TCP interface, but our input buffer was unable to hold a single byte.
-	    // Either we have not read data from our buffer for a long time, or something has gone wrong. To re-sync,
-	    // we clear the input buffer here.
-	    m_numberOfBytesInReceiveBuffer = 0;
-	}
+        ros::Time rcvTimeStamp = ros::Time::now(); // stamp received datagram
+        bool beVerboseHere = false;
+        printInfoMessage(
+            "SickScanCommonNw::readCallbackFunction(): Called with " + toString(numOfBytes) + " available bytes.",
+            beVerboseHere);
+
+        ScopedLock lock(&m_receiveDataMutex); // Mutex for access to the input buffer
+        UINT32 remainingSpace = sizeof(m_receiveBuffer) - m_numberOfBytesInReceiveBuffer;
+        UINT32 bytesToBeTransferred = numOfBytes;
+        if (remainingSpace < numOfBytes)
+        {
+            bytesToBeTransferred = remainingSpace;
+            // printWarning("SickScanCommonNw::readCallbackFunction(): Input buffer space is to small, transferring only " +
+            //              ::toString(bytesToBeTransferred) + " of " + ::toString(numOfBytes) + " bytes.");
+        }
+        else
+        {
+            // printInfoMessage("SickScanCommonNw::readCallbackFunction(): Transferring " + ::toString(bytesToBeTransferred) +
+            //                   " bytes from TCP to input buffer.", beVerboseHere);
+        }
+
+        if (bytesToBeTransferred > 0)
+        {
+            // Data can be transferred into our input buffer
+            memcpy(&(m_receiveBuffer[m_numberOfBytesInReceiveBuffer]), buffer, bytesToBeTransferred);
+            m_numberOfBytesInReceiveBuffer += bytesToBeTransferred;
+
+            UINT32 size = 0;
+
+            while (1)
+            {
+                // Now work on the input buffer until all received datasets are processed
+                SopasEventMessage frame = findFrameInReceiveBuffer();
+
+                size = frame.size();
+                if (size == 0)
+                {
+                    // Framesize = 0: There is no valid frame in the buffer. The buffer is either empty or the frame
+                    // is incomplete, so leave the loop
+                    printInfoMessage("SickScanCommonNw::readCallbackFunction(): No complete frame in input buffer, we are done.",
+                                     beVerboseHere);
+
+                    // Leave the loop
+                    break;
+                }
+                else
+                {
+                    // A frame was found in the buffer, so process it now.
+                    printInfoMessage(
+                        "SickScanCommonNw::readCallbackFunction(): Processing a frame of length " + ::toString(frame.size()) +
+                        " bytes.", beVerboseHere);
+                    processFrame(rcvTimeStamp, frame);
+                    UINT32 bytesToMove = m_numberOfBytesInReceiveBuffer - size;
+                    memmove(&(m_receiveBuffer[0]), &(m_receiveBuffer[size]), bytesToMove); // payload+magic+length+s+checksum
+                    m_numberOfBytesInReceiveBuffer = bytesToMove;
+
+                }
+            }
+        }
+        else
+        {
+            // There was input data from the TCP interface, but our input buffer was unable to hold a single byte.
+            // Either we have not read data from our buffer for a long time, or something has gone wrong. To re-sync,
+            // we clear the input buffer here.
+            m_numberOfBytesInReceiveBuffer = 0;
+        }
     }
 
 
     int SickScanAdapter::init_device()
     {
-	int portInt;
-	sscanf(port_.c_str(), "%d", &portInt);
-	m_nw.init(hostname_, portInt, disconnectFunctionS, (void*) this);
-	m_nw.setReadCallbackFunction(readCallbackFunctionS, (void*) this);
-	if (this->getEmulSensor())
-	{
-	    ARMARX_INFO_S << "Sensor emulation is switched on - network traffic is switched off.";
-	}
-	else
-	{
-	    m_nw.connect();
-	}
-	return sick_scan::ExitSuccess;
+        int portInt;
+        sscanf(port_.c_str(), "%d", &portInt);
+        m_nw.init(hostname_, portInt, disconnectFunctionS, (void*) this);
+        m_nw.setReadCallbackFunction(readCallbackFunctionS, (void*) this);
+        if (this->getEmulSensor())
+        {
+            ARMARX_INFO_S << "Sensor emulation is switched on - network traffic is switched off.";
+        }
+        else
+        {
+            m_nw.connect();
+        }
+        return sick_scan::ExitSuccess;
     }
 
     int SickScanAdapter::close_device()
     {
-	ARMARX_WARNING_S << "Disconnecting TCP-Connection.";
-	m_nw.disconnect();
-	return 0;
+        ARMARX_ERROR_S << "Disconnecting TCP-Connection.";
+        m_nw.disconnect();
+        return 0;
     }
 
 
     bool SickScanAdapter::stopScanData()
     {
-	stop_scanner();
-	return (true);
+        stop_scanner();
+        return (true);
     }
 
     void SickScanAdapter::handleRead(boost::system::error_code error, size_t bytes_transfered)
     {
-	ec_ = error;
-	bytes_transfered_ += bytes_transfered;
+        ec_ = error;
+        bytes_transfered_ += bytes_transfered;
     }
 
 
     void SickScanAdapter::checkDeadline()
     {
-	if (deadline_.expires_at() <= boost::asio::deadline_timer::traits_type::now())
-	{
-	    // The reason the function is called is that the deadline expired. Close
-	    // the socket to return all IO operations and reset the deadline
-	    socket_.close();
-	    deadline_.expires_at(boost::posix_time::pos_infin);
-	}
-
-	// Nothing bad happened, go back to sleep
-	deadline_.async_wait(boost::bind(&SickScanAdapter::checkDeadline, this));
+        if (deadline_.expires_at() <= boost::asio::deadline_timer::traits_type::now())
+        {
+            // The reason the function is called is that the deadline expired. Close
+            // the socket to return all IO operations and reset the deadline
+            socket_.close();
+            deadline_.expires_at(boost::posix_time::pos_infin);
+        }
+
+        // Nothing bad happened, go back to sleep
+        deadline_.async_wait(boost::bind(&SickScanAdapter::checkDeadline, this));
     }
 
 
     int SickScanAdapter::numberOfDatagramInInputFifo()
     {
-	int numVal = this->recvQueue.getNumberOfEntriesInQueue();
-	return (numVal);
+        int numVal = this->recvQueue.getNumberOfEntriesInQueue();
+        return (numVal);
     }
 
     int SickScanAdapter::readWithTimeout(size_t timeout_ms, char* buffer, int buffer_size, int* bytes_read,
-					 bool* exception_occured, bool isBinary)
+                                         bool* exception_occured, bool isBinary)
     {
-	// Set up the deadline to the proper timeout, error and delimiters
-	deadline_.expires_from_now(boost::posix_time::milliseconds(timeout_ms));
-	const char end_delim = static_cast<char>(0x03);
-	int dataLen = 0;
-	ec_ = boost::asio::error::would_block;
-	bytes_transfered_ = 0;
-
-	size_t to_read;
-
-	int numBytes = 0;
-	// Polling - should be changed to condition variable in the future
-	int waitingTimeInMs = 1; // try to lookup for new incoming packages
-	size_t i;
-	for (i = 0; i < timeout_ms; i += waitingTimeInMs)
-	{
-	    if (false == this->recvQueue.isQueueEmpty())
-	    {
-		break;
-	    }
-	    boost::this_thread::sleep(boost::posix_time::milliseconds(waitingTimeInMs));
-	}
-	if (i >= timeout_ms)
-	{
-	    ROS_ERROR("no answer received after %zu ms. Maybe sopas mode is wrong.\n", timeout_ms);
-	    return (sick_scan::ExitError);
-	}
-	boost::condition_variable cond_;
-	DatagramWithTimeStamp datagramWithTimeStamp = this->recvQueue.pop();
-
-	*bytes_read = datagramWithTimeStamp.datagram.size();
-	memcpy(buffer, &(datagramWithTimeStamp.datagram[0]), datagramWithTimeStamp.datagram.size());
-	return (sick_scan::ExitSuccess);
+        // Set up the deadline to the proper timeout, error and delimiters
+        deadline_.expires_from_now(boost::posix_time::milliseconds(timeout_ms));
+
+        ec_ = boost::asio::error::would_block;
+        bytes_transfered_ = 0;
+
+        // Polling - should be changed to condition variable in the future
+        int waitingTimeInMs = 1; // try to lookup for new incoming packages
+        size_t i;
+        for (i = 0; i < timeout_ms; i += waitingTimeInMs)
+        {
+            if (false == this->recvQueue.isQueueEmpty())
+            {
+                break;
+            }
+            boost::this_thread::sleep(boost::posix_time::milliseconds(waitingTimeInMs));
+        }
+        if (i >= timeout_ms)
+        {
+            ROS_ERROR("no answer received after %zu ms. Maybe sopas mode is wrong.\n", timeout_ms);
+            return (sick_scan::ExitError);
+        }
+        DatagramWithTimeStamp datagramWithTimeStamp = this->recvQueue.pop();
+
+        *bytes_read = datagramWithTimeStamp.datagram.size();
+        memcpy(buffer, &(datagramWithTimeStamp.datagram[0]), datagramWithTimeStamp.datagram.size());
+        return (sick_scan::ExitSuccess);
     }
 
     /**
@@ -1714,238 +1067,238 @@ namespace armarx
     int SickScanAdapter::sendSOPASCommand(const char* request, std::vector<unsigned char>* reply, int cmdLen)
     {
 #if 0
-	if (!socket_.is_open())
-	{
-	    ROS_ERROR("sendSOPASCommand: socket not open");
-	    diagnostics_.broadcast(getDiagnosticErrorCode(), "sendSOPASCommand: socket not open.");
-	    return sick_scan::ExitError;
-	}
+        if (!socket_.is_open())
+        {
+            ROS_ERROR("sendSOPASCommand: socket not open");
+            diagnostics_.broadcast(getDiagnosticErrorCode(), "sendSOPASCommand: socket not open.");
+            return sick_scan::ExitError;
+        }
 #endif
-	int sLen = 0;
-	int preambelCnt = 0;
-	bool cmdIsBinary = false;
-
-	if (request != NULL)
-	{
-	    sLen = cmdLen;
-	    preambelCnt = 0; // count 0x02 bytes to decide between ascii and binary command
-	    if (sLen >= 4)
-	    {
-		for (int i = 0; i < 4; i++)
-		{
-		    if (request[i] == 0x02)
-		    {
-			preambelCnt++;
-		    }
-		}
-	    }
-
-	    if (preambelCnt < 4)
-	    {
-		cmdIsBinary = false;
-	    }
-	    else
-	    {
-		cmdIsBinary = true;
-	    }
-	    int msgLen = 0;
-	    if (cmdIsBinary == false)
-	    {
-		msgLen = strlen(request);
-	    }
-	    else
-	    {
-		int dataLen = 0;
-		for (int i = 4; i < 8; i++)
-		{
-		    dataLen |= ((unsigned char) request[i] << (7 - i) * 8);
-		}
-		msgLen = 8 + dataLen + 1; // 8 Msg. Header + Packet +
-	    }
+        int sLen = 0;
+        int preambelCnt = 0;
+        bool cmdIsBinary = false;
+
+        if (request != NULL)
+        {
+            sLen = cmdLen;
+            preambelCnt = 0; // count 0x02 bytes to decide between ascii and binary command
+            if (sLen >= 4)
+            {
+                for (int i = 0; i < 4; i++)
+                {
+                    if (request[i] == 0x02)
+                    {
+                        preambelCnt++;
+                    }
+                }
+            }
+
+            if (preambelCnt < 4)
+            {
+                cmdIsBinary = false;
+            }
+            else
+            {
+                cmdIsBinary = true;
+            }
+            int msgLen = 0;
+            if (cmdIsBinary == false)
+            {
+                msgLen = strlen(request);
+            }
+            else
+            {
+                int dataLen = 0;
+                for (int i = 4; i < 8; i++)
+                {
+                    dataLen |= ((unsigned char) request[i] << (7 - i) * 8);
+                }
+                msgLen = 8 + dataLen + 1; // 8 Msg. Header + Packet +
+            }
 #if 1
-	    if (getEmulSensor())
-	    {
-		emulateReply((UINT8*) request, msgLen, reply);
-	    }
-	    else
-	    {
-		bool debugBinCmd = false;
-		if (debugBinCmd)
-		{
-		    printf("=== START HEX DUMP ===\n");
-		    for (int i = 0; i < msgLen; i++)
-		    {
-			unsigned char* ptr = (UINT8*) request;
-			printf("%02x ", ptr[i]);
-		    }
-		    printf("\n=== END HEX DUMP ===\n");
-		}
-		m_nw.sendCommandBuffer((UINT8*) request, msgLen);
-	    }
+            if (getEmulSensor())
+            {
+                emulateReply((UINT8*) request, msgLen, reply);
+            }
+            else
+            {
+                bool debugBinCmd = false;
+                if (debugBinCmd)
+                {
+                    printf("=== START HEX DUMP ===\n");
+                    for (int i = 0; i < msgLen; i++)
+                    {
+                        unsigned char* ptr = (UINT8*) request;
+                        printf("%02x ", ptr[i]);
+                    }
+                    printf("\n=== END HEX DUMP ===\n");
+                }
+                m_nw.sendCommandBuffer((UINT8*) request, msgLen);
+            }
 #else
 
-	    /*
-	     * Write a SOPAS variable read request to the device.
-	     */
-	    try
-	    {
-		boost::asio::write(socket_, boost::asio::buffer(request, msgLen));
-	    }
-	    catch (boost::system::system_error& e)
-	    {
-		ROS_ERROR("write error for command: %s", request);
-		diagnostics_.broadcast(getDiagnosticErrorCode(), "Write error for sendSOPASCommand.");
-		return sick_scan::ExitError;
-	    }
+            /*
+             * Write a SOPAS variable read request to the device.
+             */
+            try
+            {
+                boost::asio::write(socket_, boost::asio::buffer(request, msgLen));
+            }
+            catch (boost::system::system_error& e)
+            {
+                ROS_ERROR("write error for command: %s", request);
+                diagnostics_.broadcast(getDiagnosticErrorCode(), "Write error for sendSOPASCommand.");
+                return sick_scan::ExitError;
+            }
 #endif
-	}
-
-	// Set timeout in 5 seconds
-	const int BUF_SIZE = 65536;
-	char buffer[BUF_SIZE];
-	int bytes_read;
-	// !!!
-	if (getEmulSensor())
-	{
-
-	}
-	else
-	{
-	    if (readWithTimeout(getReadTimeOutInMs(), buffer, BUF_SIZE, &bytes_read, 0, cmdIsBinary) == sick_scan::ExitError)
-	    {
-		ARMARX_INFO_S << "sendSOPASCommand: no full reply available for read after (ms): " << getReadTimeOutInMs();
-		return sick_scan::ExitError;
-	    }
-
-
-	    if (reply)
-	    {
-		reply->resize(bytes_read);
-
-		std::copy(buffer, buffer + bytes_read, &(*reply)[0]);
-	    }
-	}
-	return sick_scan::ExitSuccess;
+        }
+
+        // Set timeout in 5 seconds
+        const int BUF_SIZE = 65536;
+        char buffer[BUF_SIZE];
+        int bytes_read;
+        // !!!
+        if (getEmulSensor())
+        {
+
+        }
+        else
+        {
+            if (readWithTimeout(getReadTimeOutInMs(), buffer, BUF_SIZE, &bytes_read, 0, cmdIsBinary) == sick_scan::ExitError)
+            {
+                ARMARX_INFO_S << "sendSOPASCommand: no full reply available for read after (ms): " << getReadTimeOutInMs();
+                return sick_scan::ExitError;
+            }
+
+
+            if (reply)
+            {
+                reply->resize(bytes_read);
+
+                std::copy(buffer, buffer + bytes_read, &(*reply)[0]);
+            }
+        }
+        return sick_scan::ExitSuccess;
     }
 
 
     int SickScanAdapter::get_datagram(ros::Time& recvTimeStamp, unsigned char* receiveBuffer, int bufferSize,
-				      int* actual_length,
-				      bool isBinaryProtocol, int* numberOfRemainingFifoEntries)
+                                      int* actual_length,
+                                      bool isBinaryProtocol, int* numberOfRemainingFifoEntries)
     {
-	if (NULL != numberOfRemainingFifoEntries)
-	{
-	    *numberOfRemainingFifoEntries = 0;
-	}
-	this->setReplyMode(1);
-
-	if (this->getEmulSensor())
-	{
+        if (NULL != numberOfRemainingFifoEntries)
+        {
+            *numberOfRemainingFifoEntries = 0;
+        }
+        this->setReplyMode(1);
+
+        if (this->getEmulSensor())
+        {
 #ifndef ROSSIMU
-	    // boost::this_thread::sleep(boost::posix_time::milliseconds(waitingTimeInMs));
-	    ros::Time timeStamp = ros::Time::now();
-	    uint32_t nanoSec = timeStamp.nsec;
-	    double waitTime10Hz = 10.0 * (double) nanoSec / 1E9;  // 10th of sec. [0..10[
+            // boost::this_thread::sleep(boost::posix_time::milliseconds(waitingTimeInMs));
+            ros::Time timeStamp = ros::Time::now();
+            uint32_t nanoSec = timeStamp.nsec;
+            double waitTime10Hz = 10.0 * (double) nanoSec / 1E9;  // 10th of sec. [0..10[
 
-	    uint32_t waitTime = (int) waitTime10Hz; // round down
+            uint32_t waitTime = (int) waitTime10Hz; // round down
 
-	    double waitTimeUntilNextTime10Hz = 1 / 10.0 * (1.0 - (waitTime10Hz - waitTime));
+            double waitTimeUntilNextTime10Hz = 1 / 10.0 * (1.0 - (waitTime10Hz - waitTime));
 
-	    ros::Duration(waitTimeUntilNextTime10Hz).sleep();
-	    SickScanRadar radar(this);
-	    radar.setEmulation(true);
-	    radar.simulateAsciiDatagram(receiveBuffer, actual_length);
-	    recvTimeStamp = ros::Time::now();
+            ros::Duration(waitTimeUntilNextTime10Hz).sleep();
+            SickScanRadar radar(this);
+            radar.setEmulation(true);
+            radar.simulateAsciiDatagram(receiveBuffer, actual_length);
+            recvTimeStamp = ros::Time::now();
 #endif
-	}
-	else
-	{
-	    const int maxWaitInMs = getReadTimeOutInMs();
-	    std::vector<unsigned char> dataBuffer;
+        }
+        else
+        {
+            const int maxWaitInMs = getReadTimeOutInMs();
+            std::vector<unsigned char> dataBuffer;
 #if 1 // prepared for reconnect
-	    bool retVal = this->recvQueue.waitForIncomingObject(maxWaitInMs);
-	    if (retVal == false)
-	    {
-		ARMARX_WARNING_S << "Timeout during waiting for new datagram";
-		return sick_scan::ExitError;
-	    }
-	    else
-	    {
-		// Look into receiving queue for new Datagrams
-		//
-		//
-		DatagramWithTimeStamp datagramWithTimeStamp = this->recvQueue.pop();
-		if (NULL != numberOfRemainingFifoEntries)
-		{
-		    *numberOfRemainingFifoEntries = this->recvQueue.getNumberOfEntriesInQueue();
-		}
-		recvTimeStamp = datagramWithTimeStamp.timeStamp;
-		dataBuffer = datagramWithTimeStamp.datagram;
-
-	    }
+            bool retVal = this->recvQueue.waitForIncomingObject(maxWaitInMs);
+            if (retVal == false)
+            {
+                ARMARX_ERROR_S << "Timeout during waiting for new datagram";
+                return sick_scan::ExitError;
+            }
+            else
+            {
+                // Look into receiving queue for new Datagrams
+                //
+                //
+                DatagramWithTimeStamp datagramWithTimeStamp = this->recvQueue.pop();
+                if (NULL != numberOfRemainingFifoEntries)
+                {
+                    *numberOfRemainingFifoEntries = this->recvQueue.getNumberOfEntriesInQueue();
+                }
+                recvTimeStamp = datagramWithTimeStamp.timeStamp;
+                dataBuffer = datagramWithTimeStamp.datagram;
+
+            }
 #endif
-	    // dataBuffer = this->recvQueue.pop();
-	    long size = dataBuffer.size();
-	    memcpy(receiveBuffer, &(dataBuffer[0]), size);
-	    *actual_length = size;
-	}
+            // dataBuffer = this->recvQueue.pop();
+            long size = dataBuffer.size();
+            memcpy(receiveBuffer, &(dataBuffer[0]), size);
+            *actual_length = size;
+        }
 
 #if 0
-	static int cnt = 0;
-	char szFileName[255];
-	sprintf(szFileName, "/tmp/dg%06d.bin", cnt++);
-
-	FILE* fout;
-
-	fout = fopen(szFileName, "wb");
-	if (fout != NULL)
-	{
-	    fwrite(receiveBuffer, size, 1, fout);
-	    fclose(fout);
-	}
+        static int cnt = 0;
+        char szFileName[255];
+        sprintf(szFileName, "/tmp/dg%06d.bin", cnt++);
+
+        FILE* fout;
+
+        fout = fopen(szFileName, "wb");
+        if (fout != NULL)
+        {
+            fwrite(receiveBuffer, size, 1, fout);
+            fclose(fout);
+        }
 #endif
-	return sick_scan::ExitSuccess;
-
-	if (!socket_.is_open())
-	{
-	    ROS_ERROR("get_datagram: socket not open");
-	    diagnostics_.broadcast(getDiagnosticErrorCode(), "get_datagram: socket not open.");
-	    return sick_scan::ExitError;
-	}
-
-	/*
-	 * Write a SOPAS variable read request to the device.
-	 */
-	std::vector<unsigned char> reply;
-
-	// Wait at most 5000ms for a new scan
-	size_t timeout = 30000;
-	bool exception_occured = false;
-
-	char* buffer = reinterpret_cast<char*>(receiveBuffer);
-
-	if (readWithTimeout(timeout, buffer, bufferSize, actual_length, &exception_occured, isBinaryProtocol) !=
-	    sick_scan::ExitSuccess)
-	{
-	    ROS_ERROR_THROTTLE(1.0, "get_datagram: no data available for read after %zu ms", timeout);
-	    diagnostics_.broadcast(getDiagnosticErrorCode(), "get_datagram: no data available for read after timeout.");
-
-	    // Attempt to reconnect when the connection was terminated
-	    if (!socket_.is_open())
-	    {
+        return sick_scan::ExitSuccess;
+
+        if (!socket_.is_open())
+        {
+            ROS_ERROR("get_datagram: socket not open");
+            diagnostics_.broadcast(getDiagnosticErrorCode(), "get_datagram: socket not open.");
+            return sick_scan::ExitError;
+        }
+
+        /*
+         * Write a SOPAS variable read request to the device.
+         */
+        std::vector<unsigned char> reply;
+
+        // Wait at most 5000ms for a new scan
+        size_t timeout = 30000;
+        bool exception_occured = false;
+
+        char* buffer = reinterpret_cast<char*>(receiveBuffer);
+
+        if (readWithTimeout(timeout, buffer, bufferSize, actual_length, &exception_occured, isBinaryProtocol) !=
+            sick_scan::ExitSuccess)
+        {
+            ROS_ERROR_THROTTLE(1.0, "get_datagram: no data available for read after %zu ms", timeout);
+            diagnostics_.broadcast(getDiagnosticErrorCode(), "get_datagram: no data available for read after timeout.");
+
+            // Attempt to reconnect when the connection was terminated
+            if (!socket_.is_open())
+            {
 #ifdef _MSC_VER
-		Sleep(1000);
+                Sleep(1000);
 #else
-		sleep(1);
+                sleep(1);
 #endif
-		ARMARX_INFO << "Failure - attempting to reconnect";
-		return init();
-	    }
+                ARMARX_INFO << "Failure - attempting to reconnect";
+                return init();
+            }
 
-	    return exception_occured ? sick_scan::ExitError : sick_scan::ExitSuccess;    // keep on trying
-	}
+            return exception_occured ? sick_scan::ExitError : sick_scan::ExitSuccess;    // keep on trying
+        }
 
-	return sick_scan::ExitSuccess;
+        return sick_scan::ExitSuccess;
     }
 
 }
diff --git a/source/RobotAPI/drivers/SickLaserUnit/SickScanAdapter.h b/source/RobotAPI/drivers/SickLaserUnit/SickScanAdapter.h
index d5ddd955e7d86f8f084eb4c1a277526518d947c1..76e880aaa35f6ff0df0ee0c71ba5367dddd206ea 100644
--- a/source/RobotAPI/drivers/SickLaserUnit/SickScanAdapter.h
+++ b/source/RobotAPI/drivers/SickLaserUnit/SickScanAdapter.h
@@ -36,6 +36,7 @@
 #define SICK_TIM3XX_COMMON_TCP_H
 
 #include <ArmarXCore/core/Component.h>
+#include <RobotAPI/interface/units/LaserScannerUnit.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -70,10 +71,10 @@ namespace armarx
     class SickScanAdapter : public sick_scan::SickScanCommon
     {
     public:
-        int loopOnce();
+        int loopOnce(LaserScan& scanData);
 
-        int parse_datagram(char* datagram, size_t datagram_length, sick_scan::SickScanConfig& config,
-                           sensor_msgs::LaserScan& msg, int& numEchos, int& echoMask);
+        int parseDatagram(char* datagram, size_t datagram_length, sick_scan::SickScanConfig& config,
+                          LaserScan& scanData, LaserScannerInfo& scanInfo, int& numEchos, int& echoMask, bool updateScannerInfo = false);
 
         static void disconnectFunctionS(void* obj);