Revision: 6416
http://playerstage.svn.sourceforge.net/playerstage/?rev=6416&view=rev
Author: thjc
Date: 2008-05-10 21:19:34 -0700 (Sat, 10 May 2008)
Log Message:
-----------
Merged 6393 from 2-1 branch
timing changes in nav200 and reduced sleep tiem in tcp stream
Modified Paths:
--------------
code/player/trunk/server/drivers/opaque/tcpstream.cc
code/player/trunk/server/drivers/position/nav200/nav200.cc
code/player/trunk/server/drivers/position/nav200/sicknav200.cc
Modified: code/player/trunk/server/drivers/opaque/tcpstream.cc
===================================================================
--- code/player/trunk/server/drivers/opaque/tcpstream.cc 2008-05-11
04:05:17 UTC (rev 6415)
+++ code/player/trunk/server/drivers/opaque/tcpstream.cc 2008-05-11
04:19:34 UTC (rev 6416)
@@ -323,7 +323,7 @@
if (connected)
{
- // Reads the data from the serial port and then publishes it
+ // Reads the data from the tcp server and then publishes it
ReadData();
}
else
@@ -333,7 +333,7 @@
}
// Sleep (you might, for example, block on a read() instead)
- usleep(100000);
+ usleep(1000);
}
}
Modified: code/player/trunk/server/drivers/position/nav200/nav200.cc
===================================================================
--- code/player/trunk/server/drivers/position/nav200/nav200.cc 2008-05-11
04:05:17 UTC (rev 6415)
+++ code/player/trunk/server/drivers/position/nav200/nav200.cc 2008-05-11
04:19:34 UTC (rev 6416)
@@ -722,6 +722,7 @@
return 1;
}
}
+ usleep(1000);
}
sn200->InQueue->ClearFilter();
return 0;
Modified: code/player/trunk/server/drivers/position/nav200/sicknav200.cc
===================================================================
--- code/player/trunk/server/drivers/position/nav200/sicknav200.cc
2008-05-11 04:05:17 UTC (rev 6415)
+++ code/player/trunk/server/drivers/position/nav200/sicknav200.cc
2008-05-11 04:19:34 UTC (rev 6416)
@@ -116,6 +116,10 @@
#define DEFAULT_SICKNAV200_MODE "positioning"
+/// Time to delay before we send the next position request, acceleration
performance is best
+/// When a request with velocity is sent half way through the next cycle.
+const double DEFAULT_NAV_REQUEST_DELAY_USECS = 0.06;
+
// The laser device class.
class SickNAV200 : public Driver {
public:
@@ -152,6 +156,8 @@
// Build the well known binary view of the reflector positions.
void BuildWKB();
+ player_pose2d_t GetNavVelocityInWRF();
+
protected:
// Laser pose in robot cs.
@@ -184,11 +190,7 @@
// number of values for slifing mean
IntProperty SmoothingInput;
-
-
- // Name of device used to communicate with the laser
- //char *device_name;
-
+
// storage for outgoing data
player_position2d_data_t data_packet;
@@ -213,6 +215,19 @@
player_devaddr_t position_addr;
// Vector map interface
player_devaddr_t vectormap_addr;
+
+ // delay before position update request in seconds
+ DoubleProperty NavUpdateRequestDelay;
+ // time stamping for coordinating position request timing
+ struct timeval last_nav_position_time;
+ struct timeval last_nav_request_time;
+ struct timeval last_velocity_update_time;
+
+ /// optional log file to store some timing metrics in, useful for
performance analysis of the system.
+ StringProperty TimingLogFilename;
+ FILE * TimingLogFile;
+
+
};
// a factory creation function
@@ -239,7 +254,10 @@
AutoFullMapCount("autofullmapcount", 0, false, this, cf, section),
StallCount(0),
Quality("quality", 0,true, this, cf, section),
- SmoothingInput("smoothing_input", 4, false, this, cf, section)
+ SmoothingInput("smoothing_input", 4, false, this, cf, section),
+
NavUpdateRequestDelay("update_request_delay",DEFAULT_NAV_REQUEST_DELAY_USECS,false,this,cf,section),
+ TimingLogFilename("timing_log","",true,this,cf,section),
+ TimingLogFile(NULL)
{
// Create position interface
if (cf->ReadDeviceAddr(&(this->position_addr), section, "provides",
@@ -312,7 +330,7 @@
memset(&this->reflector_map_id, 0, sizeof(this->reflector_map_id));
cf->ReadDeviceAddr(&this->reflector_map_id, section, "requires",
PLAYER_VECTORMAP_CODE, -1, NULL);
-
+
return;
}
@@ -378,6 +396,17 @@
StallCount = 0;
PLAYER_MSG0(2, "NAV200 ready");
+ // intialise logging if requested
+ if (strcmp(TimingLogFilename,""))
+ {
+ TimingLogFile = fopen(TimingLogFilename,"a");
+ if (!TimingLogFile)
+ {
+ PLAYER_ERROR2("Failed to open NAV200 timing log file
for appending: %s (%s)",errno,strerror(errno));
+ }
+ }
+
+
// Start the device thread
StartThread();
@@ -392,6 +421,12 @@
opaque->Unsubscribe(InQueue);
+ if (TimingLogFile)
+ {
+ fclose(TimingLogFile);
+ TimingLogFile = NULL;
+ }
+
PLAYER_MSG0(2, "laser shutdown");
return (0);
@@ -414,6 +449,8 @@
player_position2d_data_t * recv =
reinterpret_cast<player_position2d_data_t * >
(data);
speed = recv->vel;
+ gettimeofday(&last_velocity_update_time,NULL);
+
return 0;
}
@@ -559,6 +596,23 @@
return (-1);
}
+int usec_diff(struct timeval & then, struct timeval & now)
+{
+ return (now.tv_sec-then.tv_sec)*1000000 + (now.tv_usec-then.tv_usec);
+}
+
+int usec_elapsed(struct timeval & then)
+{
+ struct timeval now;
+ gettimeofday(&now, NULL);
+ return usec_diff(then,now);
+}
+
+double time_double(struct timeval & t)
+{
+ return static_cast<double> (t.tv_sec) + static_cast<double>
(t.tv_usec)/1e6;
+}
+
////////////////////////////////////////////////////////////////////////////////
// Main function for device thread
void SickNAV200::Main() {
@@ -589,6 +643,9 @@
FetchIfNeeded();
mode.SetValue("positioning");
}
+
+ // intialise our update timestamp
+ gettimeofday(&last_nav_position_time,NULL);
LaserPos Reading;
for (;;) {
@@ -598,54 +655,28 @@
// process any pending messages
ProcessMessages();
- double vehicleVelX = 0;
- double vehicleVelY = 0;
- double angularVelocity = 0;
bool gotReading;
- if (velocity) {
- // RCF = robot coordinate frame
- // NCF = Nav coordinate frame
- // WCF = world coordinate frame
-
- double hyp = sqrt(pose[0]*pose[0] + pose[1]*pose[1]);
- double theta = atan2(pose[1], pose[0]);
- // calculate the local nav velocities, in RCF
- double nav_tangential_vel_RCF = hyp * speed.pa;
- // calculate nav velocities in RCF
- player_pose2d_t nav_vel_RCF = speed;
- // rotational components
- nav_vel_RCF.px += nav_tangential_vel_RCF*sin(-theta);
- nav_vel_RCF.py += nav_tangential_vel_RCF*cos(-theta);
-
- // now transform to NCF, basic rotation by angle offset
- player_pose2d_t nav_vel_NCF = nav_vel_RCF;
- nav_vel_NCF.px = nav_vel_RCF.px * cos(pose[2]) -
nav_vel_RCF.py
- * sin(pose[2]);
- nav_vel_NCF.py = nav_vel_RCF.px * sin(pose[2]) +
nav_vel_RCF.py
- * cos(pose[2]);
-
- // finally transform to WRF, again just rotation
- player_pose2d_t nav_vel_WCF = nav_vel_NCF;
- nav_vel_WCF.px = nav_vel_NCF.px * cos(navAngle) -
nav_vel_NCF.py
- * sin(navAngle);
- nav_vel_WCF.py = nav_vel_NCF.px * sin(navAngle) +
nav_vel_NCF.py
- * cos(navAngle);
-
- //fprintf(stderr,"RCF: %f %f %f\n", nav_vel_RCF.px,
nav_vel_RCF.py, nav_vel_RCF.pa);
- //fprintf(stderr,"NCF: %f %f %f\n", nav_vel_NCF.px,
nav_vel_NCF.py, nav_vel_NCF.pa);
-
- while (nav_vel_WCF.pa > M_PI)
- nav_vel_WCF.pa -= M_2_PI;
- while (nav_vel_WCF.pa < -M_PI)
- nav_vel_WCF.pa += M_2_PI;
-
- short pa_in_bdeg = static_cast<short> (nav_vel_WCF.pa *
32768.0
- / M_PI);
+
+ // if less than our update delay has passed then wait until
next time through
+ if (usec_elapsed(last_nav_position_time) <
NavUpdateRequestDelay * 1e6)
+ {
+ usleep(1000);
+ continue;
+ }
+
+ if (velocity)
+ {
+ player_pose2d_t nav_vel_WCF = GetNavVelocityInWRF();
+ short pa_in_bdeg = static_cast<short> (nav_vel_WCF.pa *
32768.0 / M_PI);
//fprintf(stderr,"WCF: %f %f %f %04x\n",
nav_vel_WCF.px, nav_vel_WCF.py, nav_vel_WCF.pa, pa_in_bdeg);
-
+ gettimeofday(&last_nav_request_time,NULL);
gotReading =
Laser.GetPositionSpeedVelocityAbsolute(short(nav_vel_WCF.px * 1000),
short(nav_vel_WCF.py * 1000), pa_in_bdeg, Reading);
- } else
+ }
+ else
+ {
+ gettimeofday(&last_nav_request_time,NULL);
gotReading = Laser.GetPositionAuto(Reading);
+ }
// get update and publish result
if (gotReading) {
@@ -664,9 +695,30 @@
data_packet.pos.pa = newAngle;
data_packet.pos.px = newX;
data_packet.pos.py = newY;
- data_packet.vel.pa = angularVelocity;
- data_packet.vel.px = vehicleVelX;
- data_packet.vel.py = vehicleVelY;
+ data_packet.vel.pa = speed.pa;
+ data_packet.vel.px = speed.px;
+ data_packet.vel.py = speed.py;
+
+ // update our last request timestamp
+ struct timeval previous_update = last_nav_position_time;
+ gettimeofday(&last_nav_position_time,NULL);
+ if (TimingLogFile)
+ {
+ // Log the following data:
+ // TIMESTAMP, UPDATE_PERIOD, REQUEST_DELTA,
POSE, NAV_POSE, QUALITY, VELOCITY_DELTA, VELOCITY
+ fprintf(TimingLogFile, "%f %f %f %f %f %f %d %d
%d %d %f %f %f %f\n",
+
time_double(last_nav_position_time),
+ -static_cast<double>
(usec_diff(last_nav_position_time, previous_update))/1e6,
+ -static_cast<double>
(usec_diff(last_nav_position_time, last_nav_request_time))/1e6,
+
data_packet.pos.px,data_packet.pos.py,data_packet.pos.pa,
+
Reading.pos.x,Reading.pos.y,Reading.orientation,Reading.quality,
+ -static_cast<double>
(usec_diff(last_nav_position_time, last_velocity_update_time))/1e6,
+ speed.px,speed.py,speed.pa
+ );
+ fflush(TimingLogFile);
+ }
+
+
//printf("Got reading: quality %d\n", Reading.quality);
if (Reading.quality==0xFF || Reading.quality==0xFE
|| Reading.quality==0x00) {
@@ -971,3 +1023,45 @@
*reinterpret_cast<double*>(pointData + 13) = y;
}
}
+
+player_pose2d_t SickNAV200::GetNavVelocityInWRF()
+{
+ // RCF = robot coordinate frame
+ // NCF = Nav coordinate frame
+ // WCF = world coordinate frame
+
+ double hyp = sqrt(pose[0]*pose[0] + pose[1]*pose[1]);
+ double theta = atan2(pose[1], pose[0]);
+ // calculate the local nav velocities, in RCF
+ double nav_tangential_vel_RCF = hyp * speed.pa;
+ // calculate nav velocities in RCF
+ player_pose2d_t nav_vel_RCF = speed;
+ // rotational components
+ nav_vel_RCF.px += nav_tangential_vel_RCF*sin(-theta);
+ nav_vel_RCF.py += nav_tangential_vel_RCF*cos(-theta);
+
+ // now transform to NCF, basic rotation by angle offset
+ player_pose2d_t nav_vel_NCF = nav_vel_RCF;
+ nav_vel_NCF.px = nav_vel_RCF.px * cos(pose[2]) - nav_vel_RCF.py
+ * sin(pose[2]);
+ nav_vel_NCF.py = nav_vel_RCF.px * sin(pose[2]) + nav_vel_RCF.py
+ * cos(pose[2]);
+
+ // finally transform to WRF, again just rotation
+ player_pose2d_t nav_vel_WCF = nav_vel_NCF;
+ nav_vel_WCF.px = nav_vel_NCF.px * cos(navAngle) - nav_vel_NCF.py
+ * sin(navAngle);
+ nav_vel_WCF.py = nav_vel_NCF.px * sin(navAngle) + nav_vel_NCF.py
+ * cos(navAngle);
+
+ //fprintf(stderr,"RCF: %f %f %f\n", nav_vel_RCF.px, nav_vel_RCF.py,
nav_vel_RCF.pa);
+ //fprintf(stderr,"NCF: %f %f %f\n", nav_vel_NCF.px, nav_vel_NCF.py,
nav_vel_NCF.pa);
+
+ while (nav_vel_WCF.pa > M_PI)
+ nav_vel_WCF.pa -= M_2_PI;
+ while (nav_vel_WCF.pa < -M_PI)
+ nav_vel_WCF.pa += M_2_PI;
+
+ return nav_vel_WCF;
+}
+
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit