Revision: 6353
http://playerstage.svn.sourceforge.net/playerstage/?rev=6353&view=rev
Author: gbiggs
Date: 2008-04-17 23:51:59 -0700 (Thu, 17 Apr 2008)
Log Message:
-----------
Merging changes 4424:4428 from trunk
Modified Paths:
--------------
code/player/branches/cmake/server/drivers/position/nav200/sicknav200.cc
Modified:
code/player/branches/cmake/server/drivers/position/nav200/sicknav200.cc
===================================================================
--- code/player/branches/cmake/server/drivers/position/nav200/sicknav200.cc
2008-04-18 06:21:14 UTC (rev 6352)
+++ code/player/branches/cmake/server/drivers/position/nav200/sicknav200.cc
2008-04-18 06:51:59 UTC (rev 6353)
@@ -70,11 +70,6 @@
- Default: [0.15 0.15]
- Footprint (x,y) of the laser.
-- wheelBase (double)
- - Default: -1.0
- - Distance between front and rear wheels. Used to calculate velocities
- when vehicle movement data is provided.
-
@par Example
@verbatim
@@ -173,12 +168,9 @@
int numReflectors;
uint8_t* wkbData;
uint32_t wkbSize;
- double speed;
- double steeringAngle;
+ player_pose2d_t speed;
double navAngle;
- DoubleProperty wheelBase;
-
// If mode is set to mapping the reflector positions will be mapped,
// and mode will be automatically set back to positioning.
StringProperty mode;
@@ -235,8 +227,7 @@
// Constructor
SickNAV200::SickNAV200(ConfigFile* cf, int section)
: Driver(cf, section, true, PLAYER_MSGQUEUE_DEFAULT_MAXLEN),
- wheelBase ("wheelbase", -1.0, 0),
- mode ("mode", DEFAULT_SICKNAV200_MODE, 0)
+ mode ("mode", DEFAULT_SICKNAV200_MODE, 0, this, cf, section)
{
// Create position interface
if (cf->ReadDeviceAddr(&(this->position_addr), section,
@@ -279,8 +270,7 @@
this->wkbData = NULL;
this->wkbSize = 0;
- this->speed = 0;
- this->steeringAngle = 0;
+ memset(&this->speed, 0, sizeof(speed));
this->fetchOnStart = false;
this->navAngle = 0;
@@ -290,8 +280,6 @@
// nav200 parameters, convert to mm
this->min_radius = static_cast<int> (cf->ReadLength(section, "min_radius",
1) * 1000);
this->max_radius = static_cast<int> (cf->ReadLength(section, "max_radius",
30) * 1000);
- this->RegisterProperty ("mode", &this->mode, cf, section);
- this->RegisterProperty ("wheelbase", &this->wheelBase, cf, section);
this->opaque = NULL;
// Must have an opaque device
@@ -427,8 +415,7 @@
if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_DATA,
PLAYER_POSITION2D_DATA_STATE, velocity_id))
{
player_position2d_data_t * recv =
reinterpret_cast<player_position2d_data_t * > (data);
- speed = recv->vel.px;
- steeringAngle = recv->pos.pa;
+ speed = recv->vel;
return 0;
}
@@ -627,8 +614,6 @@
BuildWKB(); // Build an empty WKB.
- PLAYER_MSG1(2, "Wheel base: %lf", wheelBase.GetValue());
-
if (strncmp(mode, "fetch", 5) == 0)
{
fetchOnStart = true;
@@ -651,32 +636,35 @@
bool gotReading;
if (velocity)
{
- if (wheelBase.GetValue() <= 0)
- {
- PLAYER_WARN("vehicle movement data provided but wheelbase not
set. Add wheelbase to the NAV config file");
- gotReading = Laser.GetPositionAuto(Reading);
- }
- else
- {
- // Calculate the vehicles velocity
- double angle = navAngle - pose[2];
- vehicleVelX = speed * cos(angle); // Vehicle velocity in world
coordinates.
- vehicleVelY = speed * sin(angle);
- //double arcRadius = wheelBase / tan(steeringAngle);
- //double angularVelocity = speed / arcRadius;
- angularVelocity = speed * tan(steeringAngle) /
wheelBase.GetValue(); // Angular velocity of NAV and vehicle.
+ // RCF = robot coordinate frame
+ // NCF = Nav coordinate frame
+ // WCF = world coordinate frame
- // Convert vehicle movement data into NAV200 coordinates.
- double velX = speed - pose[1] * angularVelocity; // NAV vel in
vehicle coordinates.
- double velY = pose[0] * angularVelocity;
- double navVelX = velX * cos(pose[2]) + velY * sin(pose[2]);
- double navVelY = velY * cos(pose[2]) - velX * sin(pose[2]);
- //gotReading = Laser.GetPositionSpeedVelocity(short(navVelX *
1000), short(navVelY * 1000), short(angularVelocity * 32768.0 / M_PI), Reading);
- // Convert NAV200 velocity into world coordinates.
- double worldVelX = navVelX * cos(navAngle) - navVelY *
sin(navAngle);
- double worldVelY = navVelX * sin(navAngle) + navVelY *
cos(navAngle);
- gotReading =
Laser.GetPositionSpeedVelocityAbsolute(short(worldVelX * 1000), short(worldVelY
* 1000), short(angularVelocity * 32768.0 / M_PI), Reading);
- }
+ 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);
+ //fprintf(stderr,"WCF: %f %f %f\n", nav_vel_WCF.px, nav_vel_WCF.py,
nav_vel_WCF.pa);
+
+ gotReading = Laser.GetPositionSpeedVelocityAbsolute(short(nav_vel_WCF.px
* 1000), short(nav_vel_WCF.py * 1000), short(nav_vel_WCF.pa * 32768.0 / M_PI),
Reading);
}
else
gotReading = Laser.GetPositionAuto(Reading);
@@ -702,11 +690,11 @@
data_packet.vel.py = vehicleVelY;
if(Reading.quality==0xFF || Reading.quality==0xFE ||
Reading.quality==0x00)
{
- data_packet.stall = 1;
+ data_packet.stall = 1;
}
else
{
- data_packet.stall = 0;
+ data_packet.stall = 0;
}
this->Publish(this->position_addr,
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