Revision: 6998
          http://playerstage.svn.sourceforge.net/playerstage/?rev=6998&view=rev
Author:   gbiggs
Date:     2008-09-01 02:22:32 +0000 (Mon, 01 Sep 2008)

Log Message:
-----------
Applied patch 2084625

Modified Paths:
--------------
    code/player/trunk/server/drivers/rfid/CMakeLists.txt
    code/player/trunk/server/drivers/wsn/CMakeLists.txt
    code/player/trunk/server/drivers/wsn/mica2.cc

Added Paths:
-----------
    code/player/trunk/server/drivers/rfid/acr120u.cc
    code/player/trunk/server/drivers/wsn/phidgetAcc.cc

Modified: code/player/trunk/server/drivers/rfid/CMakeLists.txt
===================================================================
--- code/player/trunk/server/drivers/rfid/CMakeLists.txt        2008-09-01 
00:57:06 UTC (rev 6997)
+++ code/player/trunk/server/drivers/rfid/CMakeLists.txt        2008-09-01 
02:22:32 UTC (rev 6998)
@@ -23,3 +23,7 @@
 PLAYERDRIVER_ADD_DRIVER (phidgetRFID build_phidgetRFID
     LINKFLAGS ${phidgetExtraLibs} CFLAGS "${phidgetExtraFlags}"
     SOURCES phidgetRFID.cc)
+
+PLAYERDRIVER_OPTION (acr120u build_acr120u ON)
+PLAYERDRIVER_REQUIRE_HEADER (acr120u build_acr120u "usb.h")
+PLAYERDRIVER_ADD_DRIVER (acr120u build_acr120u LINKFLAGS "-lusb" SOURCES 
acr120u.cc)

Added: code/player/trunk/server/drivers/rfid/acr120u.cc
===================================================================
--- code/player/trunk/server/drivers/rfid/acr120u.cc                            
(rev 0)
+++ code/player/trunk/server/drivers/rfid/acr120u.cc    2008-09-01 02:22:32 UTC 
(rev 6998)
@@ -0,0 +1,415 @@
+/*
+ *  Player - One Hell of a Robot Server
+ *  Copyright (C) 2007 
+ *  Federico Ruiz Ugalde   ruizf /at/ cs.tum.edu, memeruiz /at/ gmail.com
+ *  Lorenz Moesenlechner moesenle /at/ in.tum.de
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/** @ingroup drivers */
+/** @{ */
+/** @defgroup driver_acr120u acr_120u
+ * @brief ACR120U RFID reader
+
+The acr120u driver communicates with the ACR120U (Part# ACR120U-TK-R, Firmware 
V2.2U) reader. (13.56MHz Read-Write multitag, anti-collision and USB Powered). 
+
[EMAIL PROTECTED] Compile-time dependencies
+
+- none
+
[EMAIL PROTECTED] Provides
+
+- @ref interface_rfid
+
[EMAIL PROTECTED] Requires
+
+- libusb should be installed.
+
[EMAIL PROTECTED] Configuration requests
+
+- none
+
[EMAIL PROTECTED] Configuration file options
+
+- sampling_rate (integer)
+  - Default: 200 
+  - How often (in mS) should the phidget produce data. Minimum is around 100mS
+
+- alarmtime (integer)
+  - Default: 210
+  - If the data acquisition cycle takes longer than this time (in mS), a 
warning will be printed.
+
+- provides
+  - The driver supports the "rfid" interface.
+  - No support for the buzzer and led yet.
+  
[EMAIL PROTECTED] Example 
+
[EMAIL PROTECTED]
+driver
+(
+  name "acr120u"
+  provides ["rfid:0"]
+  alwayson 0
+  samplingrate 200
+  alarmtime 210
+)
[EMAIL PROTECTED]
+
[EMAIL PROTECTED] Federico Ruiz Ugalde, Lorenz Moesenlechner
+
+ */
+/** @} */
+
+
+
+#include <libplayercore/playercore.h>
+#include <usb.h>
+
+#include <unistd.h>
+#include <string.h>
+#include <iostream>
+#include <sstream>
+
+#include <time.h>
+#include <sys/time.h>
+#include <errno.h>
+
+//This function returns the difference in mS between two timeval structures
+inline float timediffms(struct timeval start, struct timeval end) {
+    return(end.tv_sec*1000.0 + end.tv_usec/1000.0 - (start.tv_sec*1000.0 + 
start.tv_usec/1000.0));
+}
+
+class Acr120u : public Driver {
+       public:
+
+               Acr120u(ConfigFile* cf, int section);
+               ~Acr120u();
+
+               virtual int Setup();
+               virtual int Shutdown();
+
+               virtual int ProcessMessage(QueuePointer &resp_queue, 
player_msghdr * hdr, void * data);
+
+       private:
+
+               // Main function for device thread.
+               virtual void Main();
+
+               int intFromHexTuple( char c1, char c2 ) const;
+               int intFromHexTuple( const char *c ) const { return 
intFromHexTuple( c[0], c[1] ); }
+               //!Time between samples (in mS)
+               float samplingrate;
+               //!Alarm time (mS)
+               float alarmtime;
+
+               //!Libusb data
+               struct usb_bus *busses,*bus,*bus_temp;
+               usb_dev_handle *HANDLE;
+               struct usb_device *dev,*dev_temp;
+
+               typedef enum Acr120uCmds { RESET=0, TURN_ON_RADIO, LIST_TAGS };
+               static const int Acr120uCmdLength=14;
+               static const char Acr120uCmdStrings[][Acr120uCmdLength ];
+               static const int Acr120uResponseLength=3*8;
+               static const int vendorId = 0x072f;
+               static const int productId = 0x8003;
+               static const int tag_count_position = 20;
+               static const int tag_startoffset = 1;
+               
+               //! Player Interfaces
+               player_devaddr_t rfid_id;
+               //player_devaddr_t dio_id; //Use this for the buzzer and led 
latter
+};
+
+const char Acr120u::Acr120uCmdStrings[][Acr120u::Acr120uCmdLength ] =
+{
+    { 0x02, 0x30, 0x31, 0x45, 0x30, 0x30, 0x32, 0x30, 0x35, 0x30, 0x30, 0x45, 
0x36, 0x03 },      // Reset
+    { 0x02, 0x30, 0x31, 0x45, 0x30, 0x30, 0x32, 0x31, 0x33, 0x30, 0x30, 0x46, 
0x30, 0x03 },      // Turn on Radio
+    { 0x02, 0x30, 0x31, 0x45, 0x30, 0x30, 0x32, 0x30, 0x33, 0x30, 0x30, 0x45, 
0x30, 0x03 }       // List Tags
+};
+
+int Acr120u::intFromHexTuple( char c1, char c2 ) const
+{
+    char c_str[] = { c1, c2, 0x00 };
+    std::istringstream strm( c_str );
+    int num;
+
+    strm.setf( std::ios::hex, std::ios::basefield );
+    strm >> num;
+
+    return num;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Constructor.  Retrieve options from the configuration file and do any
+// pre-Setup() setup.
+Acr120u::Acr120u(ConfigFile* cf, int section)
+        : Driver(cf, section) {
+    //! Start with a clean device
+    memset(&rfid_id,0,sizeof(player_devaddr_t));
+    //memset(&dio_id,0,sizeof(player_devaddr_t)); //For the buzzer and led
+
+    // Creating the rfid interface
+    if (cf->ReadDeviceAddr(&(rfid_id), section, "provides", PLAYER_RFID_CODE, 
-1, NULL) == 0) {
+        if (AddInterface(rfid_id) != 0) {
+            SetError(-1);
+            return;
+        }
+    } else {
+        PLAYER_WARN("rfid interface not created for acr120u driver");
+    }
+    /*
+    //For the buzzer and led
+    if (cf->ReadDeviceAddr(&(dio_id), section, "provides", PLAYER_DIO_CODE, 
-1, NULL) == 0) {
+        if (AddInterface(dio_id) != 0) {
+            SetError(-1);
+            return;
+        }
+    } else {
+        PLAYER_WARN("dio interface not created for phidgetrfid driver");
+    }*/
+
+
+    // Set the libusb pointers to NULL
+    busses=0;
+    dev=0;
+    dev_temp=0;
+
+    // Read an option from the configuration file
+    //serial = cf->ReadInt(section, "serial", -1);
+
+    //Sampling rate and alarm time in mS
+    samplingrate = cf->ReadFloat(section, "samplingrate", 200.0);
+    alarmtime = cf->ReadFloat(section, "alarmtime", 210.0);
+
+    return;
+}
+
+Acr120u::~Acr120u() {}
+
+////////////////////////////////////////////////////////////////////////////////
+// Set up the device.  Return 0 if things go well, and -1 otherwise.
+int Acr120u::Setup() {
+    PLAYER_MSG0(1,"ACR120U driver initialising");
+    usb_init();
+    usb_find_busses();
+    usb_find_devices();
+    busses=usb_get_busses();
+    PLAYER_MSG0(1,"Searching for the device...");
+    int found=0;
+    while ((!found) && busses) {
+       dev_temp=busses->devices;
+       while ((!found) && dev_temp) {
+               if (dev_temp->descriptor.idVendor == 0x072f && 
dev_temp->descriptor.idProduct == 0x8003) {
+                        dev=dev_temp;
+                        HANDLE=usb_open(dev);
+                       if (usb_claim_interface(HANDLE,0) == 0) {
+                               found=1;
+                       } else {
+                               usb_close(HANDLE);
+                       }
+               }
+               dev_temp=dev_temp->next;
+       }
+       busses=busses->next;
+    }
+
+    if (found==1) {
+       PLAYER_MSG0(1,"Device found. Connection granted to the ACR120U.");
+    } else {
+       PLAYER_ERROR("There was a problem connecting to the ACR120u. You don't 
have device access permissions?");
+       return(-1); 
+    }
+
+    //Setting up the device
+    char acrResponse[Acr120uResponseLength];
+    char acrCommand[Acr120uCmdLength];
+    //Reset command
+    memcpy(acrCommand, Acr120uCmdStrings[RESET], Acr120uCmdLength);
+    usb_control_msg(HANDLE,0x40,0x00,0x00,0x00,acrCommand,Acr120uCmdLength,0);
+    for (int i=0;i<3;i++) {
+           usb_interrupt_read(HANDLE,0x01,&acrResponse[i*8],8,0);
+    }
+    //Turn on the Radio
+    memcpy(acrCommand, Acr120uCmdStrings[TURN_ON_RADIO], Acr120uCmdLength);
+    usb_control_msg(HANDLE,0x40,0x00,0x00,0x00,acrCommand,Acr120uCmdLength,0);
+    for (int i=0;i<3;i++) {
+           usb_interrupt_read(HANDLE,0x01,&acrResponse[i*8],8,0);
+    }
+
+    PLAYER_MSG0(1,"ACR120U driver ready");
+    // Start the device thread; spawns a new thread and executes
+    // Phidgetrfid::Main(), which contains the main loop for the driver.
+    StartThread();
+
+    return(0);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Shutdown the device
+int Acr120u::Shutdown() {
+
+    PLAYER_MSG0(1,"Shutting ACR120U driver down");
+    // Stop and join the driver thread
+    StopThread();
+    //Turn off the device and delete the ACR120U objects
+    //Turn power off. This is missing yet
+    //Release interface
+    usb_clear_halt(HANDLE,0);
+    usb_clear_halt(HANDLE,1);
+    usb_release_interface(HANDLE,0);
+    //Close device
+    usb_reset(HANDLE);
+    usb_close(HANDLE);
+    busses=0;
+    dev=0;
+    dev_temp=0;
+
+    PLAYER_MSG0(1,"ACR120U driver has been shutdown");
+
+    return(0);
+}
+
+int Acr120u::ProcessMessage(QueuePointer &resp_queue,
+                                      player_msghdr * hdr,
+                                      void * data) {
+    return(0);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Main function for device thread
+void Acr120u::Main() {
+
+    //Need two timers: one for calculating the sleep time to keep a desired 
framerate.
+    // The other for measuring the real elapsed time. (And maybe give an alarm)
+    struct timeval tv_framerate_start;
+    struct timeval tv_framerate_end;
+    struct timeval tv_realtime_start;
+    struct timeval tv_realtime_end;
+
+    gettimeofday( &tv_framerate_start, NULL );  // NULL -> don't want timezone 
information
+    tv_realtime_start = tv_framerate_start;
+
+    // The main loop; interact with the device here
+    while (true)  {
+        //find out the real elapsed time
+        gettimeofday( &tv_realtime_end, NULL );
+        //calculate the time in mS
+        float real_elapsed=timediffms(tv_realtime_start,tv_realtime_end);
+        //restart the timer
+        gettimeofday( &tv_realtime_start, NULL );
+
+        //check if the time was too long
+        static bool gavewarning(false);
+        if ((!gavewarning) && (real_elapsed > alarmtime)) {
+               PLAYER_WARN2("Cycle took %d mS instead of the desired %d mS. 
(Only warning once)\n",real_elapsed , samplingrate);
+       gavewarning=true;
+        }
+
+        // test if we are supposed to cancel
+        pthread_testcancel();
+
+        // Process incoming messages.  Phidgetrfid::ProcessMessage() is
+        // called on each message.
+        ProcessMessages();
+        
+        //Get the Tags
+        player_rfid_data_t data_rfid;
+       char acrCommand[Acr120uCmdLength];
+       char acrResponse[Acr120uResponseLength];
+       //ListTag
+       memcpy(acrCommand, Acr120uCmdStrings[LIST_TAGS], Acr120uCmdLength);
+       usb_control_msg(HANDLE,0x40,0x00,0x00,0x00,acrCommand,14,0);
+       for (int i=0;i<3;i++) {
+               usb_interrupt_read(HANDLE,0x01,&acrResponse[i*8],8,0);
+       }
+        data_rfid.tags_count=acrResponse[tag_count_position]-0x30;
+        data_rfid.tags = new player_rfid_tag_t[data_rfid.tags_count+1];
+
+        //Receiving Tags
+        for (unsigned int i=0;i<data_rfid.tags_count;i++) {
+               data_rfid.tags[i].guid = new char[8];
+               data_rfid.tags[i].type=1;
+               data_rfid.tags[i].guid_count=8;
+               for (int j=0;j<3;j++) {
+                       usb_interrupt_read(HANDLE,0x01,&acrResponse[j*8],8,0);
+               }
+               for (int j=0;j<8;j++) {
+                       data_rfid.tags[i].guid[7-j] = 
intFromHexTuple(&acrResponse[j*2+tag_startoffset]);
+               }
+        }
+
+        //Publishing data.
+        if (rfid_id.interf !=0) {
+            Publish(rfid_id, PLAYER_MSGTYPE_DATA, PLAYER_RFID_DATA_TAGS, 
(unsigned char*)&data_rfid, sizeof(player_rfid_data_t), NULL);
+        }
+        for (unsigned int i=0;i<data_rfid.tags_count;i++){
+               delete [] data_rfid.tags[i].guid;
+       }
+        delete [] data_rfid.tags;
+
+        //point to calculate how much to sleep, call nanosleep, after sleep 
restart the timer
+        //Get the ammount of time passed:
+        gettimeofday( &tv_framerate_end, NULL );
+        // figure out how much to sleep
+        long usecs    = tv_framerate_end.tv_usec - tv_framerate_start.tv_usec;
+        long secs     = tv_framerate_end.tv_sec  - tv_framerate_start.tv_sec;
+        long elapsed_usecs = 1000000*secs  + usecs;
+        long us_tosleep = static_cast<long>(samplingrate*1000) - elapsed_usecs;
+        struct timespec ts;
+        ts.tv_sec = 0;
+        ts.tv_nsec = us_tosleep*1000;
+        int done=nanosleep(&ts, NULL);
+
+        //restart the counter
+        gettimeofday( &tv_framerate_start, NULL );
+
+        if (done != 0) {
+            std::cout << "Error in nanosleep! ERRNO: " << errno << " ";
+            if (errno == EINTR) {
+                std::cout << "EINTR" ;
+            } else if (errno == EINVAL) {
+                std::cout << "EINVAL" ;
+            }
+            std::cout << std::endl;
+        }
+
+    }
+}
+
+// A factory creation function, declared outside of the class so that it
+// can be invoked without any object context (alternatively, you can
+// declare it static in the class).  In this function, we create and return
+// (as a generic Driver*) a pointer to a new instance of this driver.
+Driver*
+Acr120u_Init(ConfigFile* cf, int section) {
+    // Create and return a new instance of this driver
+       return((Driver*)(new Acr120u(cf, section)));
+}
+
+// A driver registration function, again declared outside of the class so
+// that it can be invoked without object context.  In this function, we add
+// the driver into the given driver table, indicating which interface the
+// driver can support and how to create a driver instance.
+void acr120u_Register(DriverTable* table) {
+       table->AddDriver("acr120u", Acr120u_Init);
+}
+

Modified: code/player/trunk/server/drivers/wsn/CMakeLists.txt
===================================================================
--- code/player/trunk/server/drivers/wsn/CMakeLists.txt 2008-09-01 00:57:06 UTC 
(rev 6997)
+++ code/player/trunk/server/drivers/wsn/CMakeLists.txt 2008-09-01 02:22:32 UTC 
(rev 6998)
@@ -19,3 +19,20 @@
     PLAYERDRIVER_OPTION (accel_calib build_accel_calib OFF "STL not found.")
 ENDIF (HAVE_STL)
 PLAYERDRIVER_ADD_DRIVER (accel_calib build_accel_calib SOURCES accel_calib.cc)
+
+PLAYERDRIVER_OPTION (phidgetAcc build_phidgetAcc ON)
+SET (PHIDGETACC_DIR "" CACHE STRING "Directory containing the Phidget Acc 
headers and libraries")
+MARK_AS_ADVANCED (PHIDGETACC_DIR)
+IF ("${PHIDGETACC_DIR}" STREQUAL "")
+    SET (phidgetReqHeader "phidget21.h")
+    SET (phidgetExtraFlags "")
+    SET (phidgetExtraLibs "-lphidget21")
+ELSE ("${PHIDGETACC_DIR}" STREQUAL "")
+    SET (phidgetReqHeader "${PHIDGETACC_DIR}/phidget21.h")
+    SET (phidgetExtraFlags "-I${PHIDGETACC_DIR}/include")
+    SET (phidgetExtraLibs "-L${PHIDGETACC_DIR}/lib -lphidget21")
+ENDIF ("${PHIDGETACC_DIR}" STREQUAL "")
+PLAYERDRIVER_REQUIRE_HEADER (phidgetAcc build_phidgetAcc ${phidgetReqHeader})
+PLAYERDRIVER_ADD_DRIVER (phidgetAcc build_phidgetAcc
+    LINKFLAGS ${phidgetExtraLibs} CFLAGS "${phidgetExtraFlags}"
+    SOURCES phidgetAcc.cc)

Modified: code/player/trunk/server/drivers/wsn/mica2.cc
===================================================================
--- code/player/trunk/server/drivers/wsn/mica2.cc       2008-09-01 00:57:06 UTC 
(rev 6997)
+++ code/player/trunk/server/drivers/wsn/mica2.cc       2008-09-01 02:22:32 UTC 
(rev 6998)
@@ -129,7 +129,12 @@
 #include <sys/ioctl.h>
 #include <math.h>
 #include <vector>
+#include <iostream>
 
+//For nanosleep:
+#include <time.h>
+#include <sys/time.h>
+
 // Includes needed for player
 #include <libplayercore/playercore.h>
 
@@ -159,6 +164,17 @@
        virtual void Main ();
        void RefreshData  ();
 
+        //!Time between samples (in mS)
+        float rfidsamplingrate;
+        //!Alarm time (mS)
+        float alarmtime;
+        //Need two timers: one for calculating the sleep time to keep a 
desired framerate.
+        // The other for measuring the real elapsed time. (And maybe give an 
alarm)
+        struct timeval tv_realtime_start;
+        struct timeval tv_realtime_end;
+        float real_elapsed;
+        bool send_rfidcmd;
+
        // Port file descriptor
        int                fd;
 
@@ -233,6 +249,12 @@
     table->AddDriver ("mica2", Mica2_Init);
 }
 
+//This function returns the difference in mS between two timeval structures
+inline float timediffms(struct timeval start, struct timeval end) {
+    return(end.tv_sec*1000.0 + end.tv_usec/1000.0 - (start.tv_sec*1000.0 + 
start.tv_usec/1000.0));
+}
+
+
 
////////////////////////////////////////////////////////////////////////////////
 // Constructor.  Retrieve options from the configuration file and do any
 // pre-Setup() setup.
@@ -270,6 +292,8 @@
 
     // Filter base node from readings ?
     filterbasenode   = cf->ReadInt (section, "filterbasenode", 0);
+    rfidsamplingrate = cf->ReadInt (section, "rfidsamplingrate", 500);
+        
 
     // Do we create a WSN interface?
     if (cf->ReadDeviceAddr (&wsn_addr, section, "provides",
@@ -351,8 +375,9 @@
 // Set up the device.  Return 0 if things go well, and -1 otherwise.
 int Mica2::Setup ()
 {
+    real_elapsed=0; 
     // Open serial port
-    fd = open (port_name, O_RDWR | O_NOCTTY);
+    fd = open (port_name, O_RDWR | O_NOCTTY | O_NONBLOCK);
     if (fd < 0)
     {
        PLAYER_ERROR2 ("> Connecting to MIB510 on [%s]; [%s]...[failed!]",
@@ -425,8 +450,8 @@
 // Main function for device thread
 void Mica2::Main ()
 {
-    timespec sleepTime = {0, 0};
-
+    gettimeofday( &tv_realtime_start, NULL );  // NULL -> don't want timezone 
information
+   
     // The main loop; interact with the device here
     while (true)
     {
@@ -440,8 +465,6 @@
        if (base_node_status != 0) // if the base node is asleep, no serial
                                   // data can be read
            RefreshData ();
-
-       nanosleep (&sleepTime, NULL);
     }
 }
 
@@ -802,12 +825,24 @@
     unsigned char buffer[255];
     // Get the time at which we started reading
     // This will be a pretty good estimate of when the phenomena occured
-    struct timeval time;
-    GlobalTime->GetTime (&time);
 
+    //find out the real elapsed time
+    gettimeofday( &tv_realtime_end, NULL );
+    //calculate the time in mS
+    real_elapsed=timediffms(tv_realtime_start,tv_realtime_end)+real_elapsed;
+    //restart the timer
+    gettimeofday( &tv_realtime_start, NULL );
+    //check if the time was too long
+    if (real_elapsed > rfidsamplingrate) {
+      send_rfidcmd=true;
+      real_elapsed=0;
+    }
+ 
     // In case the RFID interface is enabled, send a "select_tag" command first
-    if ((provideRFID) && (this->rfid_subscriptions > 0))
+    if (((provideRFID) && (this->rfid_subscriptions > 0)) && send_rfidcmd) {
+        send_rfidcmd=false;
         BuildRFIDHeader (0, NULL, 0, 0xFFFF, 1);
+    }
 
        // Reading from UART
     length = ReadSerial (buffer);
@@ -830,20 +865,26 @@
     int err, i = 0;
 
     buffer[i] = 0x7e;          // serial start byte
-    while (1) {
+    int no_read=0;
+    
+    while (no_read<100) {
        err = read (fd, &c, 1);
        if (err < 0)
        {
-           PLAYER_ERROR (">> Error reading from serial port !");
-           return (-1);
+            if (errno!=EAGAIN) {
+             PLAYER_ERROR (">> Error reading from serial port !");
+             return (-1);
+            } else { no_read++;}
        }
        if (err == 1)
        {
+           no_read=0;
            if (++i > 255) return i;
                buffer[i] = c;
            if (c == 0x7e) return i;
        }
     }
+    return 0;
 }
 
 
////////////////////////////////////////////////////////////////////////////////
@@ -883,11 +924,12 @@
 NodeCalibrationValues Mica2::FindNodeValues (unsigned int nodeID)
 {
     NodeCalibrationValues n;
-    NCV::iterator it;
 
-    for (it = ncv.begin (); it != ncv.end (); it++)
+    unsigned int i = 0;
+       
+    for (i = 0; i < ncv.size (); i++)
     {
-        n = *it;
+        n = ncv.at (i);
         if (n.node_id == nodeID)
             break;
     }
@@ -902,6 +944,8 @@
     NodeCalibrationValues node_values;
     player_wsn_data_t  wsn_data;
     player_rfid_data_t rfid_data;
+    rfid_data.tags = new player_rfid_tag_t[1];
+    rfid_data.tags[0].guid = new char[8];
     bool rfidPacket = FALSE;
     bool wsnPacket  = FALSE;
     int  i = 0, o = 2;    // index and offset
@@ -909,10 +953,6 @@
     if ((this->wsn_subscriptions < 1) && (this->rfid_subscriptions < 1))
        return -1;
 
-    // Zero data
-    memset (&wsn_data,  0, sizeof (player_wsn_data_t));
-    memset (&rfid_data, 0, sizeof (player_rfid_data_t));
-
     while (i < length)
     {
        if (buffer[o] == 0x7d)           // handle escape characters
@@ -1060,9 +1100,6 @@
 
            rfidPacket = TRUE;
 
-           player_rfid_tag_t RFIDtag;
-           memset (&RFIDtag, 0, sizeof (RFIDtag));
-
            RFIDMsg *rmsg = (RFIDMsg *)buffer;
            int dataoffset;
 
@@ -1073,6 +1110,9 @@
                response_code <<= 4;
                response_code &= 0xF0;
                response_code |= getDigit (rmsg->data[1]);
+                rfid_data.tags_count = 0;
+                rfid_data.tags[0].guid_count=0;
+                rfid_data.tags[0].type=0;
 
                if (response_code == 0x14)              // SELECT TAG pass
                {
@@ -1080,10 +1120,11 @@
                    tag_type <<= 4;
                    tag_type &= 0xF0;
                    tag_type |= getDigit (rmsg->data[3]);
-                   RFIDtag.type = tag_type;
+                    rfid_data.tags_count = 1;
+                    rfid_data.tags[0].type = tag_type;
                    dataoffset = 4;
 
-                   RFIDtag.guid_count = 8;
+                    rfid_data.tags[0].guid_count = 8;
 
                    int x = 0, cc = 0;
                    int xlength = 23 - (29 - buffer[4]);
@@ -1096,13 +1137,10 @@
                        {
                            char str[3];
                            sprintf (str, "%c%c", rmsg->data[x], 
rmsg->data[x+1]);
-                           sscanf (str, "%x", (unsigned 
int*)&RFIDtag.guid[cc]);
+                            sscanf (str, "%x", (unsigned 
int*)&rfid_data.tags[0].guid[cc]);
                            cc++;
                        }
                    }
-
-                   rfid_data.tags_count = 1;
-                   rfid_data.tags[0] = RFIDtag;
                }
            }
            break;
@@ -1121,6 +1159,8 @@
        // Write the RFID data
        Publish (rfid_addr, PLAYER_MSGTYPE_DATA, PLAYER_RFID_DATA_TAGS,
                &rfid_data, sizeof (player_rfid_data_t), NULL);
+    delete [] rfid_data.tags[0].guid;
+    delete [] rfid_data.tags;
 
     if ((provideWSN) && (wsnPacket))
        // Write the WSN data

Added: code/player/trunk/server/drivers/wsn/phidgetAcc.cc
===================================================================
--- code/player/trunk/server/drivers/wsn/phidgetAcc.cc                          
(rev 0)
+++ code/player/trunk/server/drivers/wsn/phidgetAcc.cc  2008-09-01 02:22:32 UTC 
(rev 6998)
@@ -0,0 +1,351 @@
+/*
+ *  Player - One Hell of a Robot Server
+ *  Copyright (C) 2007 Federico Ruiz Ugalde   ruizf /at/ cs.tum.edu
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/** @ingroup drivers */
+/** @{ */
+/** @defgroup driver_phidgetACC phidgetACC
+ * @brief Phidget ACC
+
+The phidgetACC driver communicates with the PhidgetACC (Part# 1059) 
accelerometer. 
+
[EMAIL PROTECTED] Compile-time dependencies
+
+- none
+
[EMAIL PROTECTED] Provides
+
+- @ref interface_wsn
+
[EMAIL PROTECTED] Requires
+
+- libphidget from www.phidgets.com should be installed.
+
[EMAIL PROTECTED] Configuration requests
+
+- none
+
[EMAIL PROTECTED] Configuration file options
+
+- serial (integer)
+  - Default: -1
+  - This defines which phidget will be controlled if there is more than one 
connected to the USB bus. 
+    You can obtain the number with lsusb, like this:  "lsusb -v |grep iSerial".
+    The default is -1 , and it will connect to the first phidget available.
+
+- sampling_rate (integer)
+  - Default: 40
+  - How often (in mS) should the phidget produce data. 40mS produces ACC data 
at a rate of 25Hz.
+
+- alarmtime (integer)
+  - Default: 45
+  - If the data acquisition cycle takes longer than this time (in mS), a 
warning will be printed.
+
+- provides
+  - The "wsn" interface with the 3 accelerometers data
+  
[EMAIL PROTECTED] Example 
+
[EMAIL PROTECTED]
+driver
+(
+  name "phidgetAcc"
+  provides ["wsn:0"]
+  serial -1
+  alwayson 1
+  samplingrate 40
+  alarmtime 45
+)
[EMAIL PROTECTED]
+
[EMAIL PROTECTED] Federico Ruiz Ugalde
+
+ */
+/** @} */
+
+
+
+#include "phidget21.h"
+#include <libplayercore/playercore.h>
+
+#include <unistd.h>
+#include <string.h>
+#include <iostream>
+
+//For nanosleep:
+#include <time.h>
+#include <sys/time.h>
+//To catch the errors of nanosleep
+#include <errno.h>
+
+//This function returns the difference in mS between two timeval structures
+inline float timediffms(struct timeval start, struct timeval end) {
+    return(end.tv_sec*1000.0 + end.tv_usec/1000.0 - (start.tv_sec*1000.0 + 
start.tv_usec/1000.0));
+}
+
+class PhidgetAcc : public Driver {
+       public:
+
+    // Constructor;
+               PhidgetAcc(ConfigFile* cf, int section);
+
+    //Destructor
+               ~PhidgetAcc();
+
+               virtual int Setup();
+               virtual int Shutdown();
+
+               virtual int ProcessMessage(QueuePointer &resp_queue, 
player_msghdr * hdr, void * data);
+
+       private:
+
+    // Main function for device thread.
+               virtual void Main();
+
+               //!Time between samples (in mS)
+               float samplingrate;
+               //!Alarm time (mS)
+               float alarmtime;
+
+               // WSN interface
+                player_wsn_data_t data;
+               
+               //! Pointer to the ACC Phidget Handle
+               CPhidgetAccelerometerHandle accel;
+
+               //! Player Interfaces
+               player_devaddr_t wsn_id;
+
+               //!Serial number of the phidget
+               int serial;
+
+//             NodeCalibrationValues FindNodeValues (unsigned int nodeID);
+               player_wsn_data_t DecodePacket (struct p_packet *pkt);
+               float ConvertAccel (unsigned short raw_accel, int neg_1g, int 
pos_1g, int converted);
+
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Constructor.  Retrieve options from the configuration file and do any
+// pre-Setup() setup.
+PhidgetAcc::PhidgetAcc(ConfigFile* cf, int section)
+        : Driver(cf, section) {
+    //! Start with a clean device
+    memset(&wsn_id,0,sizeof(player_devaddr_t));
+
+    // Creating the wsn interface
+    if (cf->ReadDeviceAddr(&(wsn_id), section, "provides", PLAYER_WSN_CODE, 
-1, NULL) == 0) {
+        if (AddInterface(wsn_id) != 0) {
+            SetError(-1);
+            return;
+        }
+    } else {
+        PLAYER_WARN("wsn interface not created for phidgetAccel driver");
+    }
+
+    // Set the phidgetwsn pointer to NULL
+    accel=0;
+
+    // Read an option from the configuration file
+    serial = cf->ReadInt(section, "serial", -1);
+
+    //Sampling rate and alarm time in mS
+    samplingrate = cf->ReadFloat(section, "samplingrate", 40.0);
+    alarmtime = cf->ReadFloat(section, "alarmtime", 45.0);
+
+    return;
+}
+
+PhidgetAcc::~PhidgetAcc() {}
+
+////////////////////////////////////////////////////////////////////////////////
+// Set up the device.  Return 0 if things go well, and -1 otherwise.
+int PhidgetAcc::Setup() {
+    PLAYER_MSG0(1,"PhidgetAccel driver initialising");
+
+    //Use the Phidgets library to communicate with the devices
+    CPhidgetAccelerometer_create(&accel);
+    CPhidget_open((CPhidgetHandle)accel,serial);
+
+    PLAYER_MSG0(1,"Waiting for Attachment.");
+
+    int status(-1);
+
+    //Wait for attachment 1s or aborts.
+    status=CPhidget_waitForAttachment((CPhidgetHandle)accel, 1000);
+
+    if (status != 0) {
+        PLAYER_ERROR("There was a problem connecting to the 
PhidgetAccelerometer.");
+        return(1);
+    } else {
+        PLAYER_MSG0(1,"Connection granted to the PhidgetAccelerometer.");
+    }
+
+    PLAYER_MSG0(1,"PhidgetAcc driver ready");
+
+    // Start the device thread; spawns a new thread and executes
+    // PhidgetAcc::Main(), which contains the main loop for the driver.
+    StartThread();
+
+    return(0);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Shutdown the device
+int PhidgetAcc::Shutdown() {
+       PLAYER_MSG0(1,"Shutting PhidgetAcc driver down");
+
+    // Stop and join the driver thread
+    StopThread();
+
+    // Turn of the device and delete the Phidget objects
+    CPhidget_close((CPhidgetHandle)accel);
+    CPhidget_delete((CPhidgetHandle)accel);
+    accel=0;
+
+    PLAYER_MSG0(1,"PhidgetAcc driver has been shutdown");
+
+    return(0);
+}
+
+int PhidgetAcc::ProcessMessage(QueuePointer &resp_queue,
+                                      player_msghdr * hdr,
+                                      void * data) {
+    return(0);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Main function for device thread
+void PhidgetAcc::Main() {
+
+    //Need two timers: one for calculating the sleep time to keep a desired 
framerate.
+    // The other for measuring the real elapsed time. (And maybe give an alarm)
+    struct timeval tv_framerate_start;
+    struct timeval tv_framerate_end;
+    struct timeval tv_realtime_start;
+    struct timeval tv_realtime_end;
+
+    gettimeofday( &tv_framerate_start, NULL );  // NULL -> don't want timezone 
information
+    tv_realtime_start = tv_framerate_start;
+
+    // The main loop; interact with the device here
+    while (true)  {
+        //find out the real elapsed time
+        gettimeofday( &tv_realtime_end, NULL );
+        //calculate the time in mS
+        float real_elapsed=timediffms(tv_realtime_start,tv_realtime_end);
+        //restart the timer
+        gettimeofday( &tv_realtime_start, NULL );
+
+        //check if the time was too long
+        static bool gavewarning(false);
+        if ((!gavewarning) && (real_elapsed > alarmtime)) {
+               PLAYER_WARN2("Cycle took %d mS instead of the desired %d mS. 
(Only warning once)\n",real_elapsed , samplingrate);
+       gavewarning=true;
+        }
+        //std::cout << real_elapsed << "mS\n";
+
+
+        // test if we are supposed to cancel
+        pthread_testcancel();
+
+        // Process incoming messages.  PhidgetAcc::ProcessMessage() is
+        // called on each message.
+        ProcessMessages();
+
+        data.node_type=1;
+        data.node_id=1;
+        data.node_parent_id=1;
+       data.data_packet.light       = -1;
+       data.data_packet.mic         = -1;
+       data.data_packet.magn_x      = -1;
+       data.data_packet.magn_y      = -1;
+       data.data_packet.magn_z      = -1;
+       data.data_packet.temperature = -1;
+       data.data_packet.battery     = -1;
+       int n_axis;
+       if(CPhidgetAccelerometer_getNumAxis(accel,&n_axis)) return;
+       double *p_accel;
+       p_accel= new double[n_axis];
+       for (int i=0;i<n_axis;++i) {
+               if(CPhidgetAccelerometer_getAcceleration(accel, i, 
&p_accel[i])) return;
+       }
+       data.data_packet.accel_x=p_accel[0];
+       data.data_packet.accel_y=p_accel[1];
+       data.data_packet.accel_z=p_accel[2];
+       delete [] p_accel;
+        
+        //Publishing data.
+        if (wsn_id.interf !=0) {
+            Publish(wsn_id, PLAYER_MSGTYPE_DATA, PLAYER_WSN_DATA_STATE, 
(unsigned char*)&data, sizeof(player_wsn_data_t), NULL);
+        }
+
+        //point to calculate how much to sleep, call nanosleep, after sleep 
restart the timer
+        //Get the ammount of time passed:
+        gettimeofday( &tv_framerate_end, NULL );
+        // figure out how much to sleep
+        long usecs    = tv_framerate_end.tv_usec - tv_framerate_start.tv_usec;
+        long secs     = tv_framerate_end.tv_sec  - tv_framerate_start.tv_sec;
+        long elapsed_usecs = 1000000*secs  + usecs;
+
+        long us_tosleep = static_cast<long>(samplingrate*1000) - elapsed_usecs;
+        //cout << "usec to sleep: " << us_tosleep << endl;
+
+        struct timespec ts;
+        ts.tv_sec = 0;
+        ts.tv_nsec = us_tosleep*1000;
+        int done=nanosleep(&ts, NULL);
+
+        //restart the counter
+        gettimeofday( &tv_framerate_start, NULL );
+
+        if (done != 0) {
+            std::cout << "Error in nanosleep! ERRNO: " << errno << " ";
+            if (errno == EINTR) {
+                std::cout << "EINTR" ;
+            } else if (errno == EINVAL) {
+                std::cout << "EINVAL" ;
+            }
+            std::cout << std::endl;
+        }
+
+    }
+}
+
+// A factory creation function, declared outside of the class so that it
+// can be invoked without any object context (alternatively, you can
+// declare it static in the class).  In this function, we create and return
+// (as a generic Driver*) a pointer to a new instance of this driver.
+Driver*
+PhidgetAcc_Init(ConfigFile* cf, int section) {
+    // Create and return a new instance of this driver
+       return((Driver*)(new PhidgetAcc(cf, section)));
+}
+
+// A driver registration function, again declared outside of the class so
+// that it can be invoked without object context.  In this function, we add
+// the driver into the given driver table, indicating which interface the
+// driver can support and how to create a driver instance.
+void phidgetAcc_Register(DriverTable* table) {
+       table->AddDriver("phidgetAcc", PhidgetAcc_Init);
+}
+


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 Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Playerstage-commit mailing list
Playerstage-commit@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to