Revision: 6602
          http://playerstage.svn.sourceforge.net/playerstage/?rev=6602&view=rev
Author:   thjc
Date:     2008-06-16 17:59:23 -0700 (Mon, 16 Jun 2008)

Log Message:
-----------
applied nav200 fixed from 2-1 [6544]

Modified Paths:
--------------
    code/player/trunk/server/drivers/position/nav200/sicknav200.cc

Modified: code/player/trunk/server/drivers/position/nav200/sicknav200.cc
===================================================================
--- code/player/trunk/server/drivers/position/nav200/sicknav200.cc      
2008-06-17 00:56:39 UTC (rev 6601)
+++ code/player/trunk/server/drivers/position/nav200/sicknav200.cc      
2008-06-17 00:59:23 UTC (rev 6602)
@@ -20,7 +20,7 @@
  *
  */
 /*
- Desc: Driver for the SICK S3000 laser
+ Desc: Driver for the SICK NAV200 laser localisation system
  Author: Toby Collett (based on lms200 by Andrew Howard)
  Date: 7 Nov 2000
  CVS: $Id$
@@ -143,8 +143,10 @@
 
        int Initialise();
        bool Initialised;
-
-
+       
+       // set device to positioning mode and set positioning mode parameters
+       int EnterPositioning();
+       
        // Get device to map reflectors.
        void UpdateMap();
        // Get the reflector positions from the device.
@@ -177,6 +179,7 @@
        uint8_t* wkbData;
        uint32_t wkbSize;
        player_pose2d_t speed;
+       player_pose2d_t odo_pos;
        double navAngle;
 
        // If mode is set to mapping the reflector positions will be mapped,
@@ -199,7 +202,10 @@
 
        // number of values for slifing mean
        IntProperty SmoothingInput;
-
+       
+       // radius of the reflectors in meters
+       DoubleProperty ReflectorRadius;
+       
        // storage for outgoing data
        player_position2d_data_t data_packet;
 
@@ -207,16 +213,20 @@
        Nav200 Laser;
        int min_radius, max_radius;
 
-       // Reflector Map Driver info
+       // Reflector Map Device info
        // Provides reflector positions if not mapped by nav200
        Device *reflector_map;
        player_devaddr_t reflector_map_id;
 
-       // Velocity Driver info
+       // Velocity Device info
        Device *velocity;
        player_devaddr_t velocity_id;
 
-       // Opaque Driver info
+       // Odometry Device info
+       Device *odometry;
+       player_devaddr_t odometry_addr;
+               
+       // Opaque Device info
        Device *opaque;
        player_devaddr_t opaque_id;
 
@@ -257,7 +267,7 @@
 
////////////////////////////////////////////////////////////////////////////////
 // Constructor
 SickNAV200::SickNAV200(ConfigFile* cf, int section) :
-       Driver(cf, section, true, PLAYER_MSGQUEUE_DEFAULT_MAXLEN),
+       Driver(cf, section, false), 
        Initialised(false),
        mode("mode", DEFAULT_SICKNAV200_MODE, false, this, cf, section),
        Nearest("nearest", 0, false, this, cf, section),
@@ -266,6 +276,7 @@
        Quality("quality", 0,true, this, cf, section),
        QualityThreshold("quality_threshold", 0,true, this, cf, section),
        SmoothingInput("smoothing_input", 4, false, this, cf, section),
+       ReflectorRadius("relector_radius",0.45,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)
@@ -334,14 +345,23 @@
        this->velocity = NULL;
        memset(&this->velocity_id, 0, sizeof(this->velocity_id));
        cf->ReadDeviceAddr(&this->velocity_id, section, "requires",
-                       PLAYER_POSITION2D_CODE, -1, NULL);
+                       PLAYER_POSITION2D_CODE, -1, "velocity");
 
+       PLAYER_MSG0(2, "reading odometry addr now");
+       this->odometry = NULL;
+       memset(&this->odometry_addr, 0, sizeof(this->odometry_addr));
+       cf->ReadDeviceAddr(&this->odometry_addr, section, "requires",
+                       PLAYER_POSITION2D_CODE, -1, "odometry");
+       
+       
        PLAYER_MSG0(2, "reading reflector map id now");
        this->reflector_map = NULL;
        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;
 }
 
@@ -372,6 +392,7 @@
                return (-1);
        }
 
+       // subscribe to velocity if it was provided, but we wait for the 
odometry otherwise we create a recursive subscription list
        if (this->velocity_id.interf == PLAYER_POSITION2D_CODE) // Velocity is 
provided.
        {
                if (!(this->velocity = 
deviceTable->GetDevice(this->velocity_id))) {
@@ -384,7 +405,7 @@
                        return (-1);
                }
        }
-
+       
        if (this->reflector_map_id.interf == PLAYER_VECTORMAP_CODE) // 
Reflector positions are provided.
        {
                if (!(this->reflector_map
@@ -457,6 +478,15 @@
                return 0;
        }
 
+       if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_DATA,
+                       PLAYER_POSITION2D_DATA_STATE, odometry_addr)) {
+               player_position2d_data_t * recv =
+                               reinterpret_cast<player_position2d_data_t * > 
(data);
+               odo_pos = recv->pos;
+               return 0;
+       }
+       
+       
        if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ,
                        PLAYER_POSITION2D_REQ_GET_GEOM, this->position_addr)) {
                player_position2d_geom_t geom= { { 0 } };
@@ -593,6 +623,7 @@
 
                this->Publish(hdr->addr, resp_queue, PLAYER_MSGTYPE_RESP_ACK,
                                PLAYER_SET_INTPROP_REQ);
+               return 0;
        }
 
        // Don't know how to handle this message.
@@ -632,22 +663,12 @@
                PLAYER_ERROR("unable to enter standby mode\n");
                return -1;
        }
-       if (!Laser.SetReflectorRadius(0, 45)) {
+       if (!Laser.SetReflectorRadius(0, static_cast<int> 
(ReflectorRadius*100))) {
                PLAYER_ERROR("unable to set reflector radius\n");
                return -1;
        }
-       if (!Laser.EnterPositioningInput(SmoothingInput)) {
-               PLAYER_ERROR("unable to enter position mode\n");
+       if (EnterPositioning() <0)
                return -1;
-       }
-       if (!Laser.SelectNearest(Nearest)) {
-               PLAYER_ERROR("unable to set nearest reflector count\n");
-               return -1;
-       }
-       if (!Laser.SetActionRadii(min_radius, max_radius)) {
-               PLAYER_ERROR("failed to set action radii\n");
-               return -1;
-       }
 
        BuildWKB(); // Build an empty WKB.
 
@@ -667,10 +688,46 @@
 
 }
 
+// set device to positioning mode and set positioning mode parameters
+int SickNAV200::EnterPositioning()
+{
+       if (!Laser.EnterPositioningInput(SmoothingInput)) {
+               PLAYER_ERROR("unable to enter position mode\n");
+               return -1;
+       }
+
+       if (!Laser.SelectNearest(Nearest)) {
+               PLAYER_ERROR("unable to set nearest reflector count\n");
+               return -1;
+       }
+       if (!Laser.SetActionRadii(min_radius, max_radius)) {
+               PLAYER_ERROR("failed to set action radii\n");
+               return -1;
+       }
+       return 0;
+}
+
+
 
////////////////////////////////////////////////////////////////////////////////
 // Main function for device thread
 void SickNAV200::Main() {
-
+       // The first thing we need to do is subscribe to the odometry
+       // this was delayed to now so we dont create dependency loops
+       // This does mean that we cannot fail as gracefully if we dont get the 
subscription
+       // so instead we just continue without odometry if we dont get the 
subscription
+       if (this->odometry_addr.interf == PLAYER_POSITION2D_CODE) // Velocity 
is provided.
+       {
+               if (!(this->odometry = 
deviceTable->GetDevice(this->odometry_addr))) {
+                       PLAYER_ERROR("unable to locate suitable position2d 
device for odometry");
+               }
+               else
+               {
+                       if (this->odometry->Subscribe(this->InQueue) != 0) {
+                               PLAYER_ERROR("unable to subscribe to position2d 
device for odometry");
+                       }
+               }
+       }
+       
        LaserPos Reading;
        for (;;) {
                // test if we are supposed to cancel
@@ -705,10 +762,11 @@
                        usleep(1000);
                        continue;
                }
-
-               if (velocity)
+               
+               player_pose2d_t nav_vel_WCF = {0,0,0};
+               if (velocity) 
                {
-                       player_pose2d_t nav_vel_WCF = GetNavVelocityInWRF();
+                       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);
@@ -742,25 +800,27 @@
                        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);
+                       struct timeval now;
+                       gettimeofday(&now,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,
+                               // TIMESTAMP, UPDATE_PERIOD, REQUEST_DELTA, 
POSE, NAV_POSE, QUALITY,NUM_REFLECTORS, VELOCITY_DELTA, VELOCITY, 
VELOCITY_NAV_WRF
+                               fprintf(TimingLogFile, "%f %f %f %f %f %f %d %d 
%d %d %d %f %f %f %f %f %f %f\n",
+                                               time_double(now), 
+                                               -static_cast<double> 
(usec_diff(now, last_nav_position_time))/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
+                                               
Reading.pos.x,Reading.pos.y,Reading.orientation,Reading.quality,Reading.number,
+                                               static_cast<double> 
(usec_diff(last_nav_position_time, last_velocity_update_time))/1e6,
+                                               speed.px,speed.py,speed.pa,
+                                               
nav_vel_WCF.px,nav_vel_WCF.py,nav_vel_WCF.pa
                                );
                                fflush(TimingLogFile);
                        }
-
-
+                       last_nav_position_time = now;
+                       
+                       
                        //printf("Got reading: quality %d\n", Reading.quality);
                        if (Reading.quality==0xFF || Reading.quality==0xFE
                                        || Reading.quality<=QualityThreshold) {
@@ -775,14 +835,21 @@
                        if (AutoFullMapCount != 0 && StallCount > 
AutoFullMapCount)
                        {
                                PLAYER_WARN1("Stalled for %d readings, 
performing full update\n", StallCount);
-                               if 
(!Laser.EnterPositioningInput(SmoothingInput)) {
+                               if (!EnterPositioning()) {
                                        PLAYER_ERROR("NAV200: ERROR on attempt 
to enter position mode, setting intialised false\n");
                                        Initialised = false;
                                        data_packet.stall =1;
                                        continue;
                                }
                        }
-
+                       else if (StallCount > 0)
+                       {
+                               short pa_in_bdeg = static_cast<short> 
(odo_pos.pa * 32768.0 / M_PI);
+                               // TODO: set layer to relevant ID once layer 
support is added
+                               PLAYER_MSG0(4,"NAV200 using odometry to try 
recover position\n");
+                               Laser.ChangeLayerDefPosition(0,static_cast<int> 
(odo_pos.px*1000),static_cast<int> (odo_pos.py*1000),pa_in_bdeg);
+                       }
+                       
                } else {
                        PLAYER_WARN("Failed to get reading from laser 
scanner\n");
                        Initialised = false;
@@ -843,7 +910,7 @@
 
        BuildWKB(); // Update wkb to show new reflectors.
 
-       if (!Laser.EnterPositioningInput(SmoothingInput)) {
+       if (!EnterPositioning()) {
                PLAYER_ERROR("Unable to return to positioning mode after 
mapping.\n");
                return;
        }
@@ -886,7 +953,7 @@
                PLAYER_ERROR("Unable to return to standby mode after getting 
reflectors.\n");
        }
 
-       if (!Laser.EnterPositioningInput(SmoothingInput)) {
+       if (!EnterPositioning()) {
                PLAYER_ERROR("Unable to return to positioning mode after 
getting reflectors.\n");
                return;
        }
@@ -977,7 +1044,7 @@
        if (!Laser.EnterStandby())
                PLAYER_ERROR("Unable to return to standby mode after getting 
reflectors.\n");
 
-       if (!Laser.EnterPositioningInput(SmoothingInput))
+       if (!EnterPositioning())
                PLAYER_ERROR("Unable to return to positioning mode after 
getting reflectors.\n");
 }
 


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to