Hi, <br>
<br>
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:<br>
<br>
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. <br>
<br>
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. <br>
<br>
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:<br>
<br>
SP_error: (-8) Connection closed by spread<br>
<br>
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. <br>
<br>
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. <br>
<br>
Thanks,<br>
<br>
Jeremy<br>
<br>
<br>
///////////////////////////////////////////////////<br>
<br>
#include <libplayerc++/playerc++.h><br>
#include <iostream><br>
#include <vector.h><br>
#include "args.h"<br>
#include <sp.h><br>
<br>
#define MAX_MESSLEN 102400<br>
<br>
struct Vertex {<br>
double x;<br>
double y;<br>
};<br>
<br>
static mailbox Mbox;<br>
static char User[80];<br>
static char Spread_name[80];<br>
static char Private_group[MAX_GROUP_NAME];<br>
<br>
int main(int argc, char **argv)<br>
{<br>
parse_args(argc,argv);<br>
<br>
// we throw exceptions on creation if we fail<br>
try<br>
{<br>
using namespace PlayerCc;<br>
<br>
PlayerClient robot(gHostname, gPort);<br>
Position2dProxy pp(&robot, gIndex);<br>
LaserProxy lp(&robot, gIndex);<br>
<br>
std::cout << robot << std::endl;<br>
<br>
//pp.SetMotorEnable (true);<br>
pp.SetOdometry(8,0,M_PI/2);<br>
<br>
double RADIUS = 8;<br>
double DIST_THRESH= 1; //1 meter<br>
double newspeed, newturnrate, range_dist;<br>
double pose_x, pose_y, pose_yaw;<br>
int FLAG;<br>
int START_DATA_GATHER=1;<br>
int STOP_DATA_GATHER=0;<br>
int ret;<br>
int numpts;<br>
char group[80];<br>
char name[80];<br>
vector<Vertex> v_pts;<br>
Vertex v_sensor, v_robot, v_global;<br>
char* vBuffer = new char[MAX_MESSLEN]; <br>
sp_time test_timeout;<br>
<br>
test_timeout.sec = 5;<br>
test_timeout.usec = 0; <br>
<br>
cout << "Please enter your user name: " << endl;<br>
cin >> User;<br>
<br>
cout << "Please enter Spread_name-- typing 'n'
will set to default (i.e. 4803@localhost): " << endl;<br>
cin >> name;<br>
if(!strcmp(name,"n"))<br>
{<br>
strcpy(Spread_name, "4803@localhost");<br>
}<br>
<br>
//ret = SP_connect_timeout( Spread_name, User, 0, 1, &Mbox, Private_group, test_timeout );<br>
ret = SP_connect( Spread_name, User, 0, 1, &Mbox, Private_group );<br>
if( ret != ACCEPT_SESSION ) <br>
{<br>
SP_error( ret );<br>
exit(0);<br>
}<br>
printf("Private_group is: %s\n", Private_group);<br>
printf("User: connected to %s with private group %s \n", Spread_name, Private_group );<br>
<br>
cout << "Please enter group to join: " << endl;<br>
cin >> group;<br>
ret = SP_join( Mbox, group );<br>
if( ret < 0 ) SP_error( ret );<br>
<br>
int count =0;<br>
for(;;)<br>
{<br>
<br>
// this blocks until new data comes; 10Hz by default<br>
robot.Read();<br>
<br>
newspeed = 1; <br>
newturnrate = 1/RADIUS;<br>
v_pts.clear();<br>
<br>
pose_x = pp.GetXPos();<br>
pose_y = pp.GetYPos();<br>
pose_yaw = pp.GetYaw();<br>
<br>
//printf("lp.GetCount(): %u\n",lp.GetCount());<br>
<br>
if(lp.GetCount()>0)<br>
{<br>
for(uint i=0;i<lp.GetCount()-1;i++)<br>
{<br>
range_dist = lp.GetRange(i+1)-lp.GetRange(i);<br>
<br>
if(FLAG==START_DATA_GATHER)<br>
{<br>
//these points are in the sensor frame<br>
v_sensor.x = lp.GetRange(i)*cos(lp.GetBearing(i));<br>
v_sensor.y = lp.GetRange(i)*sin(lp.GetBearing(i));<br>
<br>
//these points are now in the robot frame<br>
v_robot.x = cos(M_PI/2)*v_sensor.x - sin(M_PI/2)*v_sensor.y;<br>
v_robot.y = sin(M_PI/2)*v_sensor.x + cos(M_PI/2)*v_sensor.y;<br>
<br>
//these points are now in the global frame<br>
v_global.x =
cos(pp.GetYaw())*v_robot.x - sin(pp.GetYaw())*v_robot.y + pp.GetXPos();<br>
v_global.y =
sin(pp.GetYaw())*v_robot.x + cos(pp.GetYaw())*v_robot.y + pp.GetYPos();<br>
<br>
v_pts.push_back(v_global);<br>
}<br>
if(range_dist<-1*DIST_THRESH)<br>
{<br>
FLAG = START_DATA_GATHER;<br>
}<br>
else if(range_dist > DIST_THRESH)<br>
{<br>
FLAG = STOP_DATA_GATHER;<br>
}<br>
}<br>
} <br>
<br>
char* pBuffer = vBuffer;<br>
int bytesToSend = 0;<br>
numpts = v_pts.size();<br>
<br>
memcpy(pBuffer, &pose_x, sizeof(double));<br>
pBuffer += sizeof(double);<br>
bytesToSend += sizeof(double);<br>
<br>
memcpy(pBuffer, &pose_y, sizeof(double));<br>
pBuffer += sizeof(double);<br>
bytesToSend += sizeof(double);<br>
<br>
memcpy(pBuffer, &pose_yaw, sizeof(double));<br>
pBuffer += sizeof(double);<br>
bytesToSend += sizeof(double);<br>
<br>
memcpy(pBuffer, &numpts, sizeof(int));<br>
pBuffer += sizeof(int);<br>
bytesToSend += sizeof(int);<br>
<br>
for(int i=0;i<numpts;i++)<br>
{<br>
//copying v object into the location pointed to by pBuffer<br>
memcpy(pBuffer, (char*)&v_pts[i], sizeof(Vertex));<br>
pBuffer += sizeof(Vertex);<br>
bytesToSend += sizeof(Vertex);<br>
}<br>
<br>
//use SP_multigroup_multicast if sending to more than one group<br>
//printf("bytesToSend: %u \n", bytesToSend);<br>
ret= SP_multicast( Mbox, SAFE_MESS, (const char*) group, 1, bytesToSend, vBuffer );<br>
<br>
if( ret < 0 )<br>
{<br>
SP_error( ret );<br>
printf("quitting because of spread \n");<br>
exit(0);<br>
}<br>
<br>
<br>
// write commands to robot<br>
pp.SetSpeed(newspeed, newturnrate);<br>
//printf("pp.XPos(): %f pp.YPos():
%f pp.Yaw(): %f
\n",pp.GetXPos(),pp.GetYPos(),pp.GetYaw());<br>
count++;<br>
printf("messages sent: %d\n", count);<br>
<br>
}<br>
}<br>
catch (PlayerCc::PlayerError e)<br>
{<br>
std::cerr << e << std::endl;<br>
return -1;<br>
}<br>
}<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>