# Sick LMS-100 topic stops publishing measurements

Hi all,

I am using the RCPRG_laser_drivers pkg to obtain laser measurements from a sick LMS-100 laser and from a sick LMS-151 laser (each laser on a different robot, no connection between them at all).

The thing is that the laser topic stops generating messages after a while ('rostopic echo /LMS1xx/LAS_00' returns nothing when the node fails). In both cases.

Does anybody have experienced this problem?. Any suggestion how to trace this problem?

I am using Diamond Back with Ubuntu 10.04. Some weeks ago I was using CTurtle with the same laser package and I had no problem at all (tested along weeks).

• You can ping the laser once it starts to fail, even if it is not generating any message from the laser
• If the node fails, you can kill the node and restart it again, and the flow of messages will start again without problem
• I've observed that the node cannot recover from a disconnection of the laser. If you disconnect the ethernet cable to the laser, the node cannot reconnect to the laser and keep generating messages once you put the cable back. Only option is to restart the node
• I've also checked that when the node stops generating messages, there is no disconnection at all (I used a ping -f to the laser while the node was active. Once the node failed, I checked the report of ping -f (Ctrl-C) and said 0% packet loss, so there was no disconnection at all)

Any idea, comment, suggestion, bad joke, will be welcomed (specially the last one... I need jokes now :-(

Best

Ricardo

edit retag close merge delete

Sort by » oldest newest most voted

I think I found some bugs in the RCPRG laser driver. Debugging the code I saw that when laser topic stops being published, the driver gets stuck in a read of zero bytes because the buffer used to store data received from the sensor is already full (10000 bytes) without having received a valid sensor scan packet.

char buf[10000];
fd_set rfds;
struct timeval tv;
int retval, len;
len = 0;

do {
FD_ZERO(&rfds);
FD_SET(sockDesc, &rfds);

tv.tv_sec = 0;
tv.tv_usec = 50000;
retval = select(sockDesc + 1, &rfds, NULL, NULL, &tv);
if (retval) {
len += read(sockDesc, buf + len, 10000 - len);
}
} while ((buf[0] != 0x02) || (buf[len - 1] != 0x03));


The problems is more probable to happen when the scan message data includes remission values and angular resolution is set to 0.25º, because a complete message is 8192 bytes. I set the buffer dimension to 20000 and it seems to work but I think that a more elegant solution would be to use a circular buffer. Furthermore I would like to change the exit condition of the while cycle because it doesn't guarantee that the loop breaks in case of receiving a complete scan data msg + some bytes of the next one.

more

Hi,

I have the same problem, but nothing work for me. Do you have some other ideas?

I will try to reprogram the LMS1xx node for ROS. Did you make some experience with it?

Angel A.

more

Please open a new question with your specific issue so that we don't clutter this question with multiple threads of Q&A. Thanks.

( 2012-03-19 03:26:59 -0600 )edit
2

Has this problem been fixed yet?

( 2013-02-14 04:13:54 -0600 )edit

I had the same problem and I tried the solution given above but nothing worked for me.

I changed the method getData in /RCPRG_laser_drivers/libLMS1xx/build/libLMS1xx/LMS1xx.cpp to the following code

     char raw[DATA_BUF_LEN];
char buf[DATA_BUF_LEN];
int len=0;
if(leftovers.size() > 0) {

for(int i = 0; i < leftovers.size(); i++) {
buf[len] = leftovers[i];
len++;
}
leftovers.clear();
}
unsigned long start;

while(true) {
if(debug)
std::cout << "inside do while. ";

fd_set rfds;
FD_ZERO(&rfds);
FD_SET(sockDesc, &rfds);

struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 50000;

int retval = select(sockDesc + 1, &rfds, NULL, NULL, &tv); //always return the socket number
if(debug)
std::cout << "retval: " << retval << " ";
int curLen = 0;
if (retval) {

}

bool done = false;
for(int i = 0; i < curLen; i++) {
if(raw[i] == 0x03) {

leftovers.assign(raw + i + 1, raw + curLen); // copy remaining to leftovers
done = true;  // this loop is important as it copies the remaining whereas in previous there were leftovers and its never the end so was stuck in the while loop
break;
} else { //  we copy till we dont find ETX
buf[len] = raw[i];
len++;
}
}
if(debug)
std::cout << std::endl;
if(done) {
break;
}
}
// from here the code is same as before
buf[len-1]=0;
char* tok = strtok(buf, " ");
tok = strtok(NULL, " "); //Command
tok = strtok(NULL, " "); //VersionNumber
tok = strtok(NULL, " "); //DeviceNumber
tok = strtok(NULL, " "); //Serial number
tok = strtok(NULL, " "); //DeviceStatus
tok = strtok(NULL, " "); //MessageCounter
tok = strtok(NULL, " "); //ScanCounter
tok = strtok(NULL, " "); //PowerUpDuration
tok = strtok(NULL, " "); //TransmissionDuration
tok = strtok(NULL, " "); //InputStatus
tok = strtok(NULL, " "); //OutputStatus
tok = strtok(NULL, " "); //ReservedByteA
tok = strtok(NULL, " "); //ScanningFrequency
tok = strtok(NULL, " "); //MeasurementFrequency
tok = strtok(NULL, " ");
tok = strtok(NULL, " ");
tok = strtok(NULL, " ");
tok = strtok(NULL, " "); //NumberEncoders
int NumberEncoders;
sscanf(tok, "%d", &NumberEncoders);
//tok stop getting any data
for (int i = 0; i < NumberEncoders; i++) {
tok = strtok(NULL, " "); //EncoderPosition
tok = strtok(NULL, " "); //EncoderSpeed
}

tok = strtok(NULL, " "); //NumberChannels16Bit
int NumberChannels16Bit;
sscanf(tok, "%d", &NumberChannels16Bit);
if (debug)
printf("NumberChannels16Bit : %d\n", NumberChannels16Bit);
for (int i = 0; i < NumberChannels16Bit; i++) {
int type = -1; // 0 DIST1 1 DIST2 2 RSSI1 3 RSSI2
char content[6];
tok = strtok(NULL, " "); //MeasuredDataContent
sscanf(tok, "%s", content);
if (!strcmp(content, "DIST1")) {
type = 0;
} else if (!strcmp(content, "DIST2")) {
type = 1;
} else if (!strcmp(content, "RSSI1")) {
type = 2;
} else if (!strcmp(content, "RSSI2")) {
type = 3;
}
tok = strtok(NULL, " "); //ScalingFactor
tok = strtok(NULL, " "); //ScalingOffset
tok = strtok(NULL, " "); //Starting angle
tok = strtok(NULL, " "); //Angular step width
tok = strtok(NULL, " "); //NumberData
int NumberData;
sscanf(tok, "%X", &NumberData);
//std::cout<<"the type is"<<type;
if (debug)
printf("NumberData : %d\n", NumberData);

if (type == 0) {

data.dist_len1 = NumberData;

} else if (type == 1) {
data.dist_len2 = NumberData;
} else if (type == 2) {
} else if (type == 3) {
}

for (int i = 0; i < NumberData; i++) {
int dat;
tok = strtok(NULL, " "); //data
sscanf(tok, "%X", &dat);

if (type == 0) {

data.dist1[i] = dat;
} else if (type == 1) {
data.dist2[i] = dat;
} else if (type == 2) {
} else if (type == 3) {
data.rssi2 ...
more

I had a similar problem with with LMS111. I discovered that the publish rate on the laser was simply too high. To solve the problem, I loaded the manufacturer's software (a Windows program) and turned down the frequency of the laser. I believe that I dropped it from its default 50Hz to 25Hz. It has worked without fail since then.

To address the disconnection problem, you could add a check to queryStatus() every so often, and if no messages are received, you could disconnect() and then login(). I haven't needed this functionality, but it's just my thought on the matter.

Also, it is not uncommon for the laser to take ~30 seconds to begin publishing to the ROS graph properly. While this only happens once in a while, don't panic if you see it.

~ Brian

more

Thank you Brian for your answer. I made the change on the laser configuration and tested the laser along yesterday. It looks like the problem is solved. Thank you for your help!

Ricardo

more