Revision: 8150
http://playerstage.svn.sourceforge.net/playerstage/?rev=8150&view=rev
Author: gbiggs
Date: 2009-07-28 06:40:27 +0000 (Tue, 28 Jul 2009)
Log Message:
-----------
Applied patch #2825176
Modified Paths:
--------------
code/player/trunk/server/drivers/position/CMakeLists.txt
Added Paths:
-----------
code/player/trunk/server/drivers/position/segwayrmp400/
code/player/trunk/server/drivers/position/segwayrmp400/CMakeLists.txt
code/player/trunk/server/drivers/position/segwayrmp400/segwayrmp400.cc
code/player/trunk/server/drivers/position/segwayrmp400/segwayrmp400.h
Modified: code/player/trunk/server/drivers/position/CMakeLists.txt
===================================================================
--- code/player/trunk/server/drivers/position/CMakeLists.txt 2009-07-28
06:32:00 UTC (rev 8149)
+++ code/player/trunk/server/drivers/position/CMakeLists.txt 2009-07-28
06:40:27 UTC (rev 8150)
@@ -9,6 +9,7 @@
ADD_SUBDIRECTORY (motionmind)
ADD_SUBDIRECTORY (nav200)
ADD_SUBDIRECTORY (nd)
+ADD_SUBDIRECTORY (segwayrmp400)
ADD_SUBDIRECTORY (snd)
ADD_SUBDIRECTORY (roboteq)
ADD_SUBDIRECTORY (vfh)
Added: code/player/trunk/server/drivers/position/segwayrmp400/CMakeLists.txt
===================================================================
--- code/player/trunk/server/drivers/position/segwayrmp400/CMakeLists.txt
(rev 0)
+++ code/player/trunk/server/drivers/position/segwayrmp400/CMakeLists.txt
2009-07-28 06:40:27 UTC (rev 8150)
@@ -0,0 +1,2 @@
+PLAYERDRIVER_OPTION (segwayrmp400 build_segwayrmp400 ON)
+PLAYERDRIVER_ADD_DRIVER (segwayrmp400 build_segwayrmp400 SOURCES
segwayrmp400.cc)
Added: code/player/trunk/server/drivers/position/segwayrmp400/segwayrmp400.cc
===================================================================
--- code/player/trunk/server/drivers/position/segwayrmp400/segwayrmp400.cc
(rev 0)
+++ code/player/trunk/server/drivers/position/segwayrmp400/segwayrmp400.cc
2009-07-28 06:40:27 UTC (rev 8150)
@@ -0,0 +1,495 @@
+/*
+ * Player - One Hell of a Robot Server
+ * Copyright (C) 2009 Goutham Mallapragda, Anthony Cascone, Rich Mattes &
Brian Gerkey
+ *
+ * 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
+ *
+ */
+/*
+ Desc: Segway RMP 400 Driver
+ Authors: Goutham Mallapragada, Anthony Cascone, Rich Mattes
+ Updated: July 21, 2009
+*/
+
+
+/** @ingroup drivers */
+/** @{ */
+/** @defgroup driver_segwayrmp400 segwayrmp400
+ * @brief SegwayRMP400 Mobile Robot
+
+%Device driver for the Segway RMP 400, subscribes to two "segwayrmp" drivers
+
+This driver subscribes to both the front and rear modules of the RMP400 and
+provides a common interface to control the unit. It wraps two "segwayrmp"
drivers
+into a single interface and provides the same output to both units. It also
averages the
+incoming odometry and returns the combined data.
+
+This driver was developed by the Networked Robotics and Sensors Laboratory at
+The Pennsylvania State University, University Park, PA 16802.
+(http://nrsl.mne.psu.edu).
+
+...@par Note Some Dell laptops have trouble talking and staying connected to
both rmp modules.
+It is necessary to use a USB hub between the rmp units and the laptop.
+
+...@par Compile-time dependencies
+
+- none
+
+...@par Requires
+
+- @ref interface_position2d
+ - This interface is required if you chose to run the RMP400
+ from the position2d interface. The RMP400 driver can run in 2d, 3d, or both
2d and 3d modes.
+- @ref interface_position3d
+ - This interface is required if you chose to run the RMP400
+ from the position3d interface. The RMP400 driver can run in 2d, 3d, or both
2d and 3d modes.
+
+...@par Provides
+
+- @ref interface_position2d
+ - This interface returns odometry data (x,y, and yaw),
+ and accepts velocity commands (x vel and yaw vel).
+
+- @ref interface_position3d
+ - This interface returns odometry data (x, y and yaw) from the wheel
+ encoders, and attitude data (pitch and roll) from the IMU. The
+ driver accepts velocity commands (x vel and yaw vel).
+
+...@par Configuration requests
+
+- none
+
+...@par Configuration file options
+
+- fullspeed_data
+ - Default: 1
+ - If set to 0, the driver will only publish every tenth data state. This
can help
+ prevent queue overflows in certain situations since the underlying RMP
devices
+ publish their data at around 100Hz. When set to 1, all incoming data is
published.
+
+...@par Example
+
+...@verbatim
+driver
+(
+ name "segwayrmp400"
+ provides ["position2d:0" "position3d:0"]
+ requires ["front:::position3d:1" "back:::position3d:2"
"front2d:::position2d:1""back2d:::position2d:2"]
+ fullspeed_data 1
+)
+...@endverbatim
+
+...@authors Goutham Mallapragada, Anthony Cascone, Rich Mattes
+
+ */
+
+#include "segwayrmp400.h"
+
+////////////////////////////////////////////////////
+// Init
+Driver* SegwayRMP400_Init(ConfigFile* cf, int section)
+{
+ return ((Driver*)(new SegwayRMP400(cf, section)));
+}
+
+////////////////////////////////////////////////////
+// Register with drivertable
+void segwayrmp400_Register(DriverTable *table)
+{
+ table->AddDriver("segwayrmp400", SegwayRMP400_Init);
+}
+
+////////////////////////////////////////////////////
+// Constructor
+SegwayRMP400::SegwayRMP400(ConfigFile* cf, int section):
ThreadedDriver(cf,section,true, PLAYER_MSGQUEUE_DEFAULT_MAXLEN)
+{
+ // Start clean
+ this->provide_2d = false;
+ this->provide_3d = false;
+
+ memset(&this->position2d_id,0,sizeof(player_devaddr_t));
+ memset(&this->position3d_id,0,sizeof(player_devaddr_t));
+ memset(&this->segwayrmp2d_id[0],0,sizeof(player_devaddr_t));
+ memset(&this->segwayrmp2d_id[1],0,sizeof(player_devaddr_t));
+ memset(&this->segwayrmp3d_id[0],0,sizeof(player_devaddr_t));
+ memset(&this->segwayrmp3d_id[1],0,sizeof(player_devaddr_t));
+
+ newfront2d = false;
+ newback2d = false;
+ newfront3d = false;
+ newback3d = false;
+
+ // Do we create a position3d interface?
+ if(
cf->ReadDeviceAddr(&this->position3d_id,section,"provides",PLAYER_POSITION3D_CODE,-1,NULL)
== 0 )
+ {
+ if( cf->ReadDeviceAddr(&this->segwayrmp3d_id[0], section,
"requires", PLAYER_POSITION3D_CODE, -1, "front") != 0)
+ {
+ this->SetError(-1);
+ PLAYER_ERROR("Front Segway Position3d not present");
+ return;
+ }
+ if( cf->ReadDeviceAddr(&this->segwayrmp3d_id[1], section,
"requires", PLAYER_POSITION3D_CODE, -1, "back") != 0 )
+ {
+ this->SetError(-1);
+ PLAYER_ERROR("Back Segway Position2d not present");
+ return;
+ }
+
+ if(this->AddInterface(this->position3d_id)!=0)
+ {
+ this->SetError(-1);
+ PLAYER_ERROR("Unable Add SegwayRMP400 Position3d
Device");
+ return;
+ }
+
+ this->provide_3d = true;
+ PLAYER_MSG0(2, "SegwayRMP400 Providing Position3d Device");
+ }
+
+ // Do we create a position2d interface?
+ if(
cf->ReadDeviceAddr(&this->position2d_id,section,"provides",PLAYER_POSITION2D_CODE,-1,NULL)
== 0 )
+ {
+ if( cf->ReadDeviceAddr(&this->segwayrmp2d_id[0], section,
"requires", PLAYER_POSITION2D_CODE, -1, "front2d") != 0)
+ {
+ this->SetError(-1);
+ PLAYER_ERROR("Front Segway Position2d not present");
+ return;
+ }
+ if( cf->ReadDeviceAddr(&this->segwayrmp2d_id[1], section,
"requires", PLAYER_POSITION2D_CODE, -1, "back2d") != 0 )
+ {
+ this->SetError(-1);
+ PLAYER_ERROR("Back Segway Position2d not present");
+ return;
+ }
+
+ if(this->AddInterface(this->position2d_id)!=0)
+ {
+ this->SetError(-1);
+ PLAYER_ERROR("Unable Add SegwayRMP400 Position2d
Device");
+ return;
+ }
+
+ this->provide_2d = true;
+ PLAYER_MSG0(2, "SegwayRMP400 Providing Position2d Device");
+ }
+ counter = 0;
+
+ // Check config file for additional options
+ this->fullspeed = cf->ReadInt(section, "fullspeed_data", 1);
+
+
+}
+
+////////////////////////////////////////////////////
+// Setup the connections and subscribe to required devices
+int SegwayRMP400::MainSetup()
+{
+ int i;
+ PLAYER_MSG0(0,"SegwayRMP400 Initializing ...");
+
+ for( i=0; i<2; i++)
+ {
+ if (this->provide_3d)
+ {
+ if(!(this->segwayrmp3d[i] =
deviceTable->GetDevice(this->segwayrmp3d_id[i])))
+ {
+ PLAYER_ERROR1("Unable to locate segwayrmp
position3d device[%d]",i);
+ return(-1);
+ }
+ }
+ if (this->provide_2d)
+ {
+ if(!(this->segwayrmp2d[i] =
deviceTable->GetDevice(this->segwayrmp2d_id[i])))
+ {
+ PLAYER_ERROR1("Unable to locate segwayrmp
position3d device[%d]",i);
+ return(-1);
+ }
+ }
+ }
+
+ for(i=0;i<2;i++)
+ {
+ if (this->provide_3d)
+ {
+ if(this->segwayrmp3d[i]->Subscribe(this->InQueue) != 0 )
+ {
+ PLAYER_ERROR1("Unable to subscribe to host
segwayrmp position2d device[%d]",i);
+ return(-1);
+ }
+ }
+ if (this->provide_2d)
+ {
+ if(this->segwayrmp2d[i]->Subscribe(this->InQueue) != 0 )
+ {
+ PLAYER_ERROR1("Unable to subscribe to host
segwayrmp position2d device[%d]",i);
+ return(-1);
+ }
+ }
+ }
+ PLAYER_MSG0(0, "SegwayRMP Initialized");
+ return 0;
+}
+
+////////////////////////////////////////////////////
+// Shutdown connection to subscribed devices
+void SegwayRMP400::MainQuit()
+{
+ PLAYER_MSG0(0,"Shutting SegwayRMP400 down...");
+
+ if (this->provide_3d)
+ {
+ for(int i=0;i<2;i++)
+ this->segwayrmp3d[i]->Unsubscribe(this->InQueue);
+ }
+ if (this->provide_2d)
+ {
+ for(int i=0;i<2;i++)
+ this->segwayrmp2d[i]->Unsubscribe(this->InQueue);
+ }
+
+ PLAYER_MSG0(0, "SegwayRMP400 has been shutdown");
+ return;
+}
+
+////////////////////////////////////////////////////
+// Main, you get the idea
+void SegwayRMP400::Main()
+{
+ // Setup Thread
+ pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
+
+ // Main Loop
+ for(;;)
+ {
+ // Check for time to quit
+ pthread_testcancel();
+
+ // Yep, everyone has to do it.
+ ProcessMessages();
+
+ // Fill the data structure, and publish position data.
+ ProcessData();
+
+ // Sleep for 1 ms, everyone needs some sleep
+ usleep(1000);
+ }
+}
+
+////////////////////////////////////////////////////
+// Process Message because we should
+int SegwayRMP400::ProcessMessage(QueuePointer &resp_queue, player_msghdr *hdr,
void *data)
+{
+
+ // is it new position3d data?
+ if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_DATA,
PLAYER_POSITION3D_DATA_STATE, this->segwayrmp3d_id[0]))
+ {
+ assert(hdr->size == sizeof(player_position3d_data_t));
+ rmp3d_data[0] = *(player_position3d_data_t *)data;
+ newfront3d = true;
+ }
+ else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_DATA,
PLAYER_POSITION3D_DATA_STATE, this->segwayrmp3d_id[1]))
+ {
+ assert(hdr->size == sizeof(player_position3d_data_t));
+ rmp3d_data[1] = *(player_position3d_data_t *)data;
+ newback3d = true;
+ }
+
+ // is it new position3d cmd?
+ else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_CMD,
PLAYER_POSITION3D_CMD_SET_VEL, this->position3d_id))
+ {
+ return HandlePosition3DCmd((player_position3d_cmd_vel_t*)data);
+ }
+
+ // is it new position2d data?
+ else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_DATA,
PLAYER_POSITION2D_DATA_STATE, this->segwayrmp2d_id[0]))
+ {
+ assert(hdr->size == sizeof(player_position2d_data_t));
+ rmp2d_data[0] = *(player_position2d_data_t *)data;
+ newfront2d = true;
+ }
+ else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_DATA,
PLAYER_POSITION2D_DATA_STATE, this->segwayrmp2d_id[1]))
+ {
+ assert(hdr->size == sizeof(player_position2d_data_t));
+ rmp2d_data[1] = *(player_position2d_data_t *)data;
+ newback2d = true;
+ }
+
+ // is it new position2d cmd?
+ else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_CMD,
PLAYER_POSITION2D_CMD_VEL, this->position2d_id))
+ {
+ return HandlePosition2DCmd((player_position2d_cmd_vel_t*)data);
+ }
+
+ // is it a geometry request?
+ else
if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,PLAYER_POSITION2D_REQ_GET_GEOM,this->position2d_id))
+ {
+ player_position2d_geom_t geom;
+ geom.pose.px = 0;
+ geom.pose.py = 0;
+ geom.pose.pyaw = 0;
+ geom.size.sw = 0.508;
+ geom.size.sl = 0.610;
+
+ this->Publish(position2d_id, PLAYER_MSGTYPE_RESP_ACK,
PLAYER_POSITION2D_REQ_GET_GEOM, &geom, sizeof(geom),NULL);
+ }
+
+ // pass the request to the underlying segway rmp position devices for 2d
+ else
if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,-1,this->position2d_id))
+ {
+ Message *msg;
+ //@TODO: compare responses of both segways.
+ // hack: sending both segways the command, forwarding the
response of the second segway rmp only;
+ msg =
this->segwayrmp2d[0]->Request(this->InQueue,hdr->type,hdr->subtype,(void*)data,hdr->size,&hdr->timestamp);
+ msg =
this->segwayrmp2d[1]->Request(this->InQueue,hdr->type,hdr->subtype,(void*)data,hdr->size,&hdr->timestamp);
+
+ player_msghdr_t* rephdr = msg->GetHeader();
+ void* repdata = msg->GetPayload();
+ rephdr->addr = this->position2d_id;
+ this->Publish(resp_queue,rephdr,repdata);
+ delete msg;
+ }
+
+ // pass the request to the underlying segway rmp position devices for 3d
+ else
if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,-1,this->position3d_id))
+ {
+ Message *msg;
+ //@TODO: Compare responses of both segways.
+ // hack: sending both segways the command, forwarding the
response of the second segway rmp only;
+ msg =
this->segwayrmp3d[0]->Request(this->InQueue,hdr->type,hdr->subtype,(void*)data,hdr->size,&hdr->timestamp);
+ msg =
this->segwayrmp3d[1]->Request(this->InQueue,hdr->type,hdr->subtype,(void*)data,hdr->size,&hdr->timestamp);
+
+ player_msghdr_t* rephdr = msg->GetHeader();
+ void* repdata = msg->GetPayload();
+ rephdr->addr = this->position3d_id;
+ this->Publish(resp_queue,rephdr,repdata);
+ delete msg;
+ }
+
+ // is it something we can't handle?
+ else
+ return -1;
+
+ // if all went well
+ return 0;
+}
+
+////////////////////////////////////////////////////
+// Simple function to forward position 3d commands
+int SegwayRMP400::HandlePosition3DCmd(player_position3d_cmd_vel_t *cmd)
+{
+
+ for(int i=0;i<2;i++)
+ {
+ // Push the message forward to each of the subscribed devices
+ this->segwayrmp3d[i]->PutMsg(this->InQueue,
PLAYER_MSGTYPE_CMD,
+
PLAYER_POSITION3D_CMD_SET_VEL,
+
(void*)cmd,sizeof(player_position3d_cmd_vel_t),NULL);
+ }
+ return 0;
+}
+
+////////////////////////////////////////////////////
+// Simple function to forward position 2d commands
+int SegwayRMP400::HandlePosition2DCmd(player_position2d_cmd_vel_t *cmd)
+{
+
+ for(int i=0;i<2;i++)
+ {
+ // Push the message forward to each of the subscribed devices
+ this->segwayrmp2d[i]->PutMsg(this->InQueue,
PLAYER_MSGTYPE_CMD,
+
PLAYER_POSITION2D_CMD_VEL,
+
(void*)cmd,sizeof(player_position2d_cmd_vel_t),NULL);
+ }
+ return 0;
+}
+
+////////////////////////////////////////////////////
+// Simple function to package position data and publish
+// Makes an effort to not use or publish duplicate data.
+void SegwayRMP400::ProcessData()
+{
+ /// @todo
+ /// Add smarter approach to combine the data from both RMPs. For now,
just average.
+
+ bool pos3dready = false;
+ bool pos2dready = false;
+
+ // Repackage the position3d data if we have new data from both
interfaces
+ if (newfront3d && newback3d)
+ {
+ position3d_data.pos.px = (rmp3d_data[0].pos.px +
rmp3d_data[1].pos.px)/2.0;
+ position3d_data.pos.py = (rmp3d_data[0].pos.py +
rmp3d_data[1].pos.py)/2.0;
+ position3d_data.pos.pz = (rmp3d_data[0].pos.pz +
rmp3d_data[1].pos.pz)/2.0;
+ position3d_data.pos.proll = (rmp3d_data[0].pos.proll +
rmp3d_data[1].pos.proll)/2.0;
+ position3d_data.pos.ppitch = (rmp3d_data[0].pos.ppitch +
rmp3d_data[1].pos.ppitch)/2.0;
+ position3d_data.pos.pyaw = (rmp3d_data[0].pos.pyaw +
rmp3d_data[1].pos.pyaw)/2.0;
+
+ position3d_data.vel.px = (rmp3d_data[0].vel.px +
rmp3d_data[1].vel.px)/2.0;
+ position3d_data.vel.py = (rmp3d_data[0].vel.py +
rmp3d_data[1].vel.py)/2.0;
+ position3d_data.vel.pz = (rmp3d_data[0].vel.pz +
rmp3d_data[1].vel.pz)/2.0;
+ position3d_data.vel.proll = (rmp3d_data[0].vel.proll +
rmp3d_data[1].vel.proll)/2.0;
+ position3d_data.vel.ppitch = (rmp3d_data[0].vel.ppitch +
rmp3d_data[1].vel.ppitch)/2.0;
+ position3d_data.vel.pyaw = (rmp3d_data[0].vel.pyaw +
rmp3d_data[1].vel.pyaw)/2.0;
+
+ newfront3d = false;
+ newback3d = false;
+ pos3dready = true;
+ }
+
+ // Repackage the position 2d data if we have new data from both
interfaces
+ if (newfront2d && newback2d)
+ {
+ position2d_data.pos.px = (rmp2d_data[0].pos.px +
rmp2d_data[1].pos.px)/2.0;
+ position2d_data.pos.py = (rmp2d_data[0].pos.py +
rmp2d_data[1].pos.py)/2.0;
+ position2d_data.pos.pa = (rmp2d_data[0].pos.pa +
rmp2d_data[1].pos.pa)/2.0;
+
+ position2d_data.vel.px = (rmp2d_data[0].vel.px +
rmp2d_data[1].vel.px)/2.0;
+ position2d_data.vel.py = (rmp2d_data[0].vel.py +
rmp2d_data[1].vel.py)/2.0;
+ position2d_data.vel.pa = (rmp2d_data[0].vel.pa +
rmp2d_data[1].vel.pa)/2.0;
+
+ newfront2d = false;
+ newback2d = false;
+ pos2dready = true;
+ }
+
+ // Publish every tenth message from both interfaces, making sure it's
new data.
+ if (!fullspeed && counter >= 10)
+ {
+ if (pos3dready)
+ this->Publish(position3d_id, PLAYER_MSGTYPE_DATA,
PLAYER_POSITION3D_DATA_STATE,
+
(void*)&position3d_data,sizeof(position3d_data),NULL);
+ if (pos2dready)
+ this->Publish(position2d_id, PLAYER_MSGTYPE_DATA,
PLAYER_POSITION2D_DATA_STATE,
+
(void*)&position2d_data,sizeof(position2d_data),NULL);
+ counter = 0;
+ }
+
+ // Publish all valid messages we are able to combine, only uses new
data.
+ else if (fullspeed)
+ {
+ if (pos3dready)
+ this->Publish(position3d_id, PLAYER_MSGTYPE_DATA,
PLAYER_POSITION3D_DATA_STATE,
+
(void*)&position3d_data,sizeof(position3d_data),NULL);
+ if (pos2dready)
+ this->Publish(position2d_id, PLAYER_MSGTYPE_DATA,
PLAYER_POSITION2D_DATA_STATE,
+
(void*)&position2d_data,sizeof(position2d_data),NULL);
+ counter = 0;
+ }
+
+ counter++;
+
+
+
+}
Added: code/player/trunk/server/drivers/position/segwayrmp400/segwayrmp400.h
===================================================================
--- code/player/trunk/server/drivers/position/segwayrmp400/segwayrmp400.h
(rev 0)
+++ code/player/trunk/server/drivers/position/segwayrmp400/segwayrmp400.h
2009-07-28 06:40:27 UTC (rev 8150)
@@ -0,0 +1,105 @@
+/*
+ * Player - One Hell of a Robot Server
+ * Copyright (C) 2009 Goutham Mallapragda, Anthony Cascone, Rich Mattes &
Brian Gerkey
+ *
+ * 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
+ *
+ */
+/*
+ Desc: Segway RMP 400 Driver
+ Authors: Goutham Mallapragada, Anthony Cascone, Rich Mattes
+ Updated: July 21, 2009
+*/
+
+#ifndef __SEGWAYRMP400_H_
+#define __SEGWAYRMP400_H_
+
+#include <stdio.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include <libplayercore/playercore.h>
+
+
+/// SegwayRMP400 Position Driver
+class SegwayRMP400 : public ThreadedDriver
+{
+
+public:
+
+ /// Standard Constructor
+ SegwayRMP400(ConfigFile* cf, int section);
+
+ /// Initialize (Player Standard)
+ virtual int MainSetup();
+
+ /// Shutdown (Player Standard)
+ virtual void MainQuit();
+
+private:
+
+ // Devices
+ Device* segwayrmp2d[2]; ///< child segwayrmp200
devices for 2d subsrciption
+ Device* segwayrmp3d[2]; ///< child segwayrmp200
devices for 3d subsrciption
+
+ // Device Addresses
+ player_devaddr_t segwayrmp2d_id[2]; ///< 2d Position
Interface Address (Output)
+ player_devaddr_t segwayrmp3d_id[2]; ///< 3d Position
Interface Address (Output)
+
+ player_devaddr_t position3d_id; ///< 3d Position
Interface Address (Input)
+ player_devaddr_t position2d_id; ///< 2d Position
Interface Address (Input)
+
+ // Device Data Structures
+ player_position2d_data_t rmp2d_data[2]; ///< Incoming data from
child segwayrmp200 devices 2d
+ player_position3d_data_t rmp3d_data[2]; ///< Incoming data from
child segwayrmp200 devices 3d
+
+ player_position2d_data_t position2d_data; ///< Output data for
parent segwayrmp400 device 2d
+ player_position2d_cmd_vel_t position2d_cmd; ///< Output cmd for
parent segwayrmp400 device 2d
+
+ player_position3d_data_t position3d_data; ///< Output data for
parent segwayrmp400 device 3d
+ player_position3d_cmd_vel_t position3d_cmd; ///< Output cmd for
parent segwayrmp400 device 3d
+
+ // Flags
+ bool provide_2d; ///< Provide 2d
interface Flag
+ bool provide_3d; ///< Provide 3d
interface Flag
+
+ int counter;
+ /// Main
+ void Main();
+
+ /// Process message function (Player Standard)
+ int ProcessMessage(QueuePointer &resp_queue, player_msghdr_t* hdr,
void* data);
+
+ /// Packages position data and publishes
+ void ProcessData();
+
+ /// Internal method to handle position 3D commands
+ int HandlePosition3DCmd(player_position3d_cmd_vel_t* cmd);
+
+ /// Internal method to handle position 2D commands
+ int HandlePosition2DCmd(player_position2d_cmd_vel_t* cmd);
+
+ /// Flags for new data
+ bool newfront3d, newback3d, newfront2d, newback2d;
+
+ /// Flag for full speed data reporting.
+ bool fullspeed;
+};
+
+#endif
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now. http://p.sf.net/sfu/bobj-july
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit