[Spread-users] Spread disconnects after ~1500 messages sent

Jeremy Ma jeremy.ma at gmail.com
Tue Dec 26 16:09:03 EST 2006


I've installed Spread3.17.3 and am using it in a multi-agent robotics
application where each robot communicates with a peer using Spread
messaging. I'm having this reoccurring problem that I just cannot figure

On the sender side, I have a single agent first connect to the Spread
Daemon, then join a group, and then after joining the group, broadcast
position information and a set of 361 data points (that come from a laser
scanner) --encoded appropriately in a long character string-- to the group
in a neverending for loop.

On the receiver side, I join the group and receive the long string of data,
parse it and plot it through some openGL program I wrote.

When i test my program in simulation, I have the daemon, sender, and
receiver all running on my local machine through different terminals. I'm
noticing that after about ~1500 messages are sent from the sender, the
sender program quits with the following message:

SP_error: (-8) Connection closed by spread

And it's not always after the same number of messages sent that the program
quits. Sometimes, it send about 1553 messages or 1519 messages and so forth
and quits.

Does anyone know why this is? I'm guessing it has something to do with a
buffer being filled or something but I cannot figure it out. I've attached
the sender code that I'm using.




#include <libplayerc++/playerc++.h>
#include <iostream>
#include <vector.h>
#include "args.h"
#include <sp.h>

#define MAX_MESSLEN   102400

struct Vertex {
double x;
double y;

static  mailbox Mbox;
static    char    User[80];
static  char    Spread_name[80];
static  char    Private_group[MAX_GROUP_NAME];

int main(int argc, char **argv)

  // we throw exceptions on creation if we fail
    using namespace PlayerCc;

    PlayerClient robot(gHostname, gPort);
    Position2dProxy pp(&robot, gIndex);
    LaserProxy lp(&robot, gIndex);

    std::cout << robot << std::endl;

    //pp.SetMotorEnable (true);

    double RADIUS = 8;
    double DIST_THRESH= 1; //1 meter
    double newspeed, newturnrate, range_dist;
    double pose_x, pose_y, pose_yaw;
    int FLAG;
    int ret;
    int numpts;
    char group[80];
    char name[80];
    vector<Vertex> v_pts;
    Vertex v_sensor, v_robot, v_global;
    char* vBuffer = new char[MAX_MESSLEN];
    sp_time test_timeout;

    test_timeout.sec = 5;
    test_timeout.usec = 0;

    cout << "Please enter your user name: " << endl;
    cin >> User;

    cout << "Please enter Spread_name-- typing 'n' will set to default (i.e.
4803 at localhost): " << endl;
    cin >> name;
    strcpy(Spread_name, "4803 at localhost");

    //ret = SP_connect_timeout( Spread_name, User, 0, 1, &Mbox,
Private_group, test_timeout );
    ret = SP_connect( Spread_name, User, 0, 1, &Mbox, Private_group );
    if( ret != ACCEPT_SESSION )
    SP_error( ret );
    printf("Private_group is: %s\n", Private_group);
    printf("User: connected to %s with private group %s \n", Spread_name,
Private_group );

    cout << "Please enter group to join: " << endl;
    cin >> group;
    ret = SP_join( Mbox, group );
    if( ret < 0 ) SP_error( ret );

    int count =0;

    // this blocks until new data comes; 10Hz by default

    newspeed = 1;
    newturnrate = 1/RADIUS;

    pose_x = pp.GetXPos();
    pose_y = pp.GetYPos();
    pose_yaw = pp.GetYaw();

    //printf("lp.GetCount(): %u\n",lp.GetCount());

        for(uint i=0;i<lp.GetCount()-1;i++)
        range_dist = lp.GetRange(i+1)-lp.GetRange(i);

            //these points are in the sensor frame
            v_sensor.x = lp.GetRange(i)*cos(lp.GetBearing(i));
            v_sensor.y = lp.GetRange(i)*sin(lp.GetBearing(i));

            //these points are now in the robot frame
            v_robot.x = cos(M_PI/2)*v_sensor.x - sin(M_PI/2)*v_sensor.y;
            v_robot.y = sin(M_PI/2)*v_sensor.x + cos(M_PI/2)*v_sensor.y;

            //these points are now in the global frame
            v_global.x = cos(pp.GetYaw())*v_robot.x -
+ pp.GetXPos();
            v_global.y = sin(pp.GetYaw())*v_robot.x +
+ pp.GetYPos();

        else if(range_dist > DIST_THRESH)
            FLAG = STOP_DATA_GATHER;

    char* pBuffer = vBuffer;
    int bytesToSend = 0;
    numpts = v_pts.size();

    memcpy(pBuffer, &pose_x, sizeof(double));
    pBuffer += sizeof(double);
    bytesToSend += sizeof(double);

    memcpy(pBuffer, &pose_y, sizeof(double));
    pBuffer += sizeof(double);
    bytesToSend += sizeof(double);

    memcpy(pBuffer, &pose_yaw, sizeof(double));
    pBuffer += sizeof(double);
    bytesToSend += sizeof(double);

    memcpy(pBuffer, &numpts, sizeof(int));
    pBuffer += sizeof(int);
    bytesToSend += sizeof(int);

    for(int i=0;i<numpts;i++)
        //copying v object into the location pointed to by pBuffer
        memcpy(pBuffer, (char*)&v_pts[i], sizeof(Vertex));
        pBuffer += sizeof(Vertex);
        bytesToSend += sizeof(Vertex);

    //use SP_multigroup_multicast if sending to more than one group
    //printf("bytesToSend: %u \n", bytesToSend);
    ret= SP_multicast( Mbox, SAFE_MESS, (const char*) group, 1, bytesToSend,
vBuffer );

    if( ret < 0 )
        SP_error( ret );
        printf("quitting because of spread \n");

    // write commands to robot
    pp.SetSpeed(newspeed, newturnrate);
    //printf("pp.XPos(): %f   pp.YPos(): %f   pp.Yaw(): %f  \n",pp.GetXPos
    printf("messages sent: %d\n", count);

  catch (PlayerCc::PlayerError e)
      std::cerr << e << std::endl;
      return -1;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.spread.org/pipermail/spread-users/attachments/20061226/996e9a44/attachment.html 

More information about the Spread-users mailing list