[Spread-users] Spread disconnects after ~1500 messages sent
Jeremy Ma
jeremy.ma at gmail.com
Tue Dec 26 16:09:03 EST 2006
Hi,
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
out:
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.
Thanks,
Jeremy
///////////////////////////////////////////////////
#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)
{
parse_args(argc,argv);
// we throw exceptions on creation if we fail
try
{
using namespace PlayerCc;
PlayerClient robot(gHostname, gPort);
Position2dProxy pp(&robot, gIndex);
LaserProxy lp(&robot, gIndex);
std::cout << robot << std::endl;
//pp.SetMotorEnable (true);
pp.SetOdometry(8,0,M_PI/2);
double RADIUS = 8;
double DIST_THRESH= 1; //1 meter
double newspeed, newturnrate, range_dist;
double pose_x, pose_y, pose_yaw;
int FLAG;
int START_DATA_GATHER=1;
int STOP_DATA_GATHER=0;
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;
if(!strcmp(name,"n"))
{
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 );
exit(0);
}
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;
for(;;)
{
// this blocks until new data comes; 10Hz by default
robot.Read();
newspeed = 1;
newturnrate = 1/RADIUS;
v_pts.clear();
pose_x = pp.GetXPos();
pose_y = pp.GetYPos();
pose_yaw = pp.GetYaw();
//printf("lp.GetCount(): %u\n",lp.GetCount());
if(lp.GetCount()>0)
{
for(uint i=0;i<lp.GetCount()-1;i++)
{
range_dist = lp.GetRange(i+1)-lp.GetRange(i);
if(FLAG==START_DATA_GATHER)
{
//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 -
sin(pp.GetYaw())*v_robot.y
+ pp.GetXPos();
v_global.y = sin(pp.GetYaw())*v_robot.x +
cos(pp.GetYaw())*v_robot.y
+ pp.GetYPos();
v_pts.push_back(v_global);
}
if(range_dist<-1*DIST_THRESH)
{
FLAG = START_DATA_GATHER;
}
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");
exit(0);
}
// write commands to robot
pp.SetSpeed(newspeed, newturnrate);
//printf("pp.XPos(): %f pp.YPos(): %f pp.Yaw(): %f \n",pp.GetXPos
(),pp.GetYPos(),pp.GetYaw());
count++;
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