Revision: 6489
          http://playerstage.svn.sourceforge.net/playerstage/?rev=6489&view=rev
Author:   thjc
Date:     2008-06-09 00:25:44 -0700 (Mon, 09 Jun 2008)

Log Message:
-----------
merged nav fixes 6424,6435,6446 and 6448 from 2-1 patches

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

Modified: code/player/trunk/server/drivers/position/nav200/nav200.cc
===================================================================
--- code/player/trunk/server/drivers/position/nav200/nav200.cc  2008-06-07 
01:15:39 UTC (rev 6488)
+++ code/player/trunk/server/drivers/position/nav200/nav200.cc  2008-06-09 
07:25:44 UTC (rev 6489)
@@ -1,6 +1,7 @@
 #include "nav200.h"
 
 
+
 Nav200::Nav200()
 {
 }
@@ -585,6 +586,27 @@
   player_opaque_data_t mData;
   mData.data_count = length;
   mData.data = buffer;
+
+  // before we send a command to the NAV200, flush and data coming in from the 
remote file
+  sn200->InQueue->SetFilter(opaque_id.host, opaque_id.robot, opaque_id.interf, 
opaque_id.index, PLAYER_MSGTYPE_DATA, PLAYER_OPAQUE_DATA_STATE);
+  
+  //puts("waiting for data");
+  sn200->ProcessMessages();
+  
+  // before we send a command to the NAV200, flush and data coming in from the 
remote file
+  if (bytesReceived)
+  {
+
+    do
+    {
+        PLAYER_WARN1("Buffer was not empty on NAV200 (%d), 
flushing",bytesReceived);
+        bytesReceived = 0;
+       usleep(100000);
+       sn200->ProcessMessages();
+    } while (bytesReceived != 0);
+  }
+  sn200->InQueue->ClearFilter();
+  
   opaque->PutMsg(sn200->InQueue, PLAYER_MSGTYPE_CMD, PLAYER_OPAQUE_CMD_DATA, 
reinterpret_cast<void*>(&mData), 0, NULL);
   
 /*  if((length && (write(fd, buffer, length)) < length))
@@ -626,12 +648,6 @@
   
   for (;;)
   {
-    gettimeofday(&now,NULL);
-    if ((now.tv_sec - start.tv_sec) * 1e6 + now.tv_usec - start.tv_usec > 
timeout_usec)
-    {
-      fprintf(stderr,"Timed out waiting for packet %d uSecs 
passed\n",static_cast<int>((now.tv_sec - start.tv_sec) * 1e6 + now.tv_usec - 
start.tv_usec));
-      return -1;
-    }
     //puts("waiting for data");
     sn200->ProcessMessages();
     
@@ -722,6 +738,13 @@
         return 1;
       }
     }
+    gettimeofday(&now,NULL);
+    if ((now.tv_sec - start.tv_sec) * 1e6 + now.tv_usec - start.tv_usec > 
timeout_usec)
+    {
+      fprintf(stderr,"Timed out waiting for packet %d uSecs 
passed\n",static_cast<int>((now.tv_sec - start.tv_sec) * 1e6 + now.tv_usec - 
start.tv_usec));
+      sn200->InQueue->ClearFilter();
+      return -1;
+    }
     usleep(1000);
   }
   sn200->InQueue->ClearFilter();

Modified: code/player/trunk/server/drivers/position/nav200/sicknav200.cc
===================================================================
--- code/player/trunk/server/drivers/position/nav200/sicknav200.cc      
2008-06-07 01:15:39 UTC (rev 6488)
+++ code/player/trunk/server/drivers/position/nav200/sicknav200.cc      
2008-06-09 07:25:44 UTC (rev 6489)
@@ -93,7 +93,9 @@
  */
 /** @} */
 
+#if HAVE_CONFIG_H
 #include <config.h>
+#endif
 
 #include <assert.h>
 #include <math.h>
@@ -118,7 +120,7 @@
 
 /// 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; 
+const double DEFAULT_NAV_REQUEST_DELAY_USECS = 0.06;
 
 // The laser device class.
 class SickNAV200 : public Driver {
@@ -139,6 +141,10 @@
        // Main function for device thread.
        virtual void Main();
 
+       int Initialise();
+       bool Initialised;
+
+
        // Get device to map reflectors.
        void UpdateMap();
        // Get the reflector positions from the device.
@@ -157,7 +163,7 @@
        void BuildWKB();
 
        player_pose2d_t GetNavVelocityInWRF();
-       
+
 protected:
 
        // Laser pose in robot cs.
@@ -188,9 +194,12 @@
        // the current quality report
        IntProperty Quality;
 
+       // the threshold for quality. Treat anything less than this threshold 
as a stall
+       IntProperty QualityThreshold;
+
        // number of values for slifing mean
        IntProperty SmoothingInput;
-       
+
        // storage for outgoing data
        player_position2d_data_t data_packet;
 
@@ -215,19 +224,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
@@ -249,11 +258,13 @@
 // Constructor
 SickNAV200::SickNAV200(ConfigFile* cf, int section) :
        Driver(cf, section, true, PLAYER_MSGQUEUE_DEFAULT_MAXLEN),
+       Initialised(false),
        mode("mode", DEFAULT_SICKNAV200_MODE, false, this, cf, section),
        Nearest("nearest", 0, false, this, cf, section),
        AutoFullMapCount("autofullmapcount", 0, false, this, cf, section),
        StallCount(0),
        Quality("quality", 0,true, this, cf, section),
+       QualityThreshold("quality_threshold", 0,true, 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),
@@ -330,7 +341,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;
 }
 
@@ -342,7 +353,7 @@
 
////////////////////////////////////////////////////////////////////////////////
 // Set up the device
 int SickNAV200::Setup() {
-       PLAYER_MSG0(2, "NAV200 initialising");
+       PLAYER_MSG0(2, "NAV200 Setup");
 
        // Subscribe to the opaque device.
        if (Device::MatchDeviceAddress(this->opaque_id, this->position_addr)
@@ -388,14 +399,6 @@
                }
        }
 
-       // Open the terminal
-       Laser.Initialise(this, opaque, opaque_id);
-       PLAYER_MSG0(2, "Laser initialised");
-
-       // reset our stall count
-       StallCount = 0;
-       PLAYER_MSG0(2, "NAV200 ready");
-
        // intialise logging if requested
        if (strcmp(TimingLogFilename,""))
        {
@@ -405,8 +408,8 @@
                        PLAYER_ERROR2("Failed to open NAV200 timing log file 
for appending: %s (%s)",errno,strerror(errno));
                }
        }
-       
-       
+
+
        // Start the device thread
        StartThread();
 
@@ -426,7 +429,7 @@
                fclose(TimingLogFile);
                TimingLogFile = NULL;
        }
-       
+
        PLAYER_MSG0(2, "laser shutdown");
 
        return (0);
@@ -606,34 +609,44 @@
        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() {
+int SickNAV200::Initialise()
+{
+       PLAYER_MSG0(2, "Nav200: Initialising connection to device");
+       if (Initialised)
+               return 0;
+
+       // Open the terminal
+       Laser.Initialise(this, opaque, opaque_id);
+
+       // reset our stall count
+       StallCount = 0;
+
        if (!Laser.EnterStandby()) {
                PLAYER_ERROR("unable to enter standby mode\n");
+               return -1;
        }
        if (!Laser.SetReflectorRadius(0, 45)) {
                PLAYER_ERROR("unable to set reflector radius\n");
-               return;
+               return -1;
        }
        if (!Laser.EnterPositioningInput(SmoothingInput)) {
                PLAYER_ERROR("unable to enter position mode\n");
-               return;
+               return -1;
        }
        if (!Laser.SelectNearest(Nearest)) {
                PLAYER_ERROR("unable to set nearest reflector count\n");
-               return;
+               return -1;
        }
        if (!Laser.SetActionRadii(min_radius, max_radius)) {
                PLAYER_ERROR("failed to set action radii\n");
-               return;
+               return -1;
        }
 
        BuildWKB(); // Build an empty WKB.
@@ -643,28 +656,57 @@
                FetchIfNeeded();
                mode.SetValue("positioning");
        }
-       
+
        // intialise our update timestamp
        gettimeofday(&last_nav_position_time,NULL);
 
+       PLAYER_MSG0(2, "NAV200 ready");
+
+       Initialised = true;
+       return 0;
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Main function for device thread
+void SickNAV200::Main() {
+
        LaserPos Reading;
        for (;;) {
                // test if we are supposed to cancel
                pthread_testcancel();
 
+               // we keep publishing data even if we are stalled, or 
disconnected
+               // this lets clients know we are at least still trying.
+               this->Publish(this->position_addr, PLAYER_MSGTYPE_DATA,
+                               PLAYER_POSITION2D_DATA_STATE, 
(void*)&data_packet,
+                               sizeof(data_packet), NULL);
+
                // process any pending messages
                ProcessMessages();
 
+               if (!Initialised)
+               {
+                       Initialise();
+                       if (!Initialised)
+                       {
+                               usleep(200000); // sleep for slightly longer 
than the nominal nav update (135ms)
+                               data_packet.stall =1;
+                               continue;
+                       }
+               }
+
+
                bool gotReading;
-               
-               // if less than our update delay has passed then wait until 
next time through 
+
+               // 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) 
+
+               if (velocity)
                {
                        player_pose2d_t nav_vel_WCF = GetNavVelocityInWRF();
                        short pa_in_bdeg = static_cast<short> (nav_vel_WCF.pa * 
32768.0 / M_PI);
@@ -672,7 +714,7 @@
                        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);
@@ -707,7 +749,7 @@
                                // 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), 
+                                               
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,
@@ -717,11 +759,11 @@
                                );
                                fflush(TimingLogFile);
                        }
-                       
-                       
+
+
                        //printf("Got reading: quality %d\n", Reading.quality);
                        if (Reading.quality==0xFF || Reading.quality==0xFE
-                                       || Reading.quality==0x00) {
+                                       || Reading.quality<=QualityThreshold) {
                                data_packet.stall = 1;
                                StallCount = StallCount + 1;
                                Quality = 0;
@@ -734,21 +776,18 @@
                        {
                                PLAYER_WARN1("Stalled for %d readings, 
performing full update\n", StallCount);
                                if 
(!Laser.EnterPositioningInput(SmoothingInput)) {
-                                       PLAYER_ERROR("unable to enter position 
mode\n");
-                                       return;
+                                       PLAYER_ERROR("NAV200: ERROR on attempt 
to enter position mode, setting intialised false\n");
+                                       Initialised = false;
+                                       data_packet.stall =1;
+                                       continue;
                                }
                        }
 
-
-                       this->Publish(this->position_addr, PLAYER_MSGTYPE_DATA,
-                                       PLAYER_POSITION2D_DATA_STATE, 
(void*)&data_packet,
-                                       sizeof(data_packet), NULL);
                } else {
                        PLAYER_WARN("Failed to get reading from laser 
scanner\n");
-                       sleep(1);
-                       // May have been disconnected. Attempt to return to 
positioning mode.
-                       if (fetchOnStart)
-                               FetchIfNeeded();
+                       Initialised = false;
+                       data_packet.stall = 1;
+                       continue;
                }
        }
 }
@@ -1061,7 +1100,7 @@
                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.

-------------------------------------------------------------------------
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