⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 segwayrmp.cc

📁 机器人仿真软件
💻 CC
📖 第 1 页 / 共 3 页
字号:
/* *  Player - One Hell of a Robot Server *  Copyright (C) 2003  John Sweeney & 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: Driver for the Segway RMP  Author: John Sweeney and Brian Gerkey  Date:  CVS: $Id: segwayrmp.cc,v 1.40.2.2 2006/06/09 01:17:52 gerkey Exp $*//** @ingroup drivers *//** @{ *//** @defgroup driver_segwayrmp segwayrmp * @brief Segway RMP mobile robot@todo This driver is currently disabled because it needs to be updated tothe Player 2.0 API.The driver has been updated to the point that it compiles, but a few key requestshave been disabled and it has not been tested in anyway.The segwayrmp driver provides control of a Segway RMP (RoboticMobility Platform), which is an experimental robotic version of theSegway HT (Human Transport), a kind of two-wheeled, self-balancingelectric scooter.@par Compile-time dependencies- libcanlib (from Kvaser)@par Notes- Because of its power, weight, height, and dynamics, the Segway RMP isa potentially dangerous machine.  Be @e very careful with it.- Although the RMP does not actually support motor power control from software, for safety you must explicitly enable the motors using a@p PLAYER_POSITION_MOTOR_POWER_REQ or @p PLAYER_POSITION3D_MOTOR_POWER_REQ(depending on which interface you are using).  You must @e also enablethe motors in the command packet, by setting the @p state field to 1.- For safety, this driver will stop the RMP (i.e., send zero velocities)if no new command has been received from a client in the previous 400ms or so.Thus, even if you want to continue moving at a constant velocity, you mustcontinuously send your desired velocities.- Most of the configuration requests have not been tested.- Currently, the only supported type of CAN I/O is "kvaser", which usesKvaser, Inc.'s CANLIB interface library.  This library provides accessto CAN cards made by Kvaser, such as the LAPcan II.  However, the CANI/O subsystem within this driver is modular, so that it should be prettystraightforward to add support for other CAN cards.@par Provides- @ref interface_position2d  - This interface returns odometry data, and accepts velocity commands.- @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).- @ref interface_power  - Returns the current battery voltage (72 V when fully charged).@par Configuration requests- position interface  - PLAYER_POSITION_POWER_REQ- position3d interface  - PLAYER_POSITION_POWER_REQ@par Requires- none@par Configuration file options- canio (string)  - Default: "kvaser"  - Type of CANbus driver.- max_xspeed (length / sec)  - Default: 0.5 m/s  - Maximum linear speed- max_yawspeed (angle / sec)  - Default: 40 deg/sec  - Maximum angular speed      @par Example @verbatimdriver(  name "segwayrmp"  provides ["position:0" "position3d:0" "power:0"])@endverbatim@author John Sweeney, Brian Gerkey, Andrew Howard*//** @} */  #include <sys/types.h>#include <netinet/in.h>#include <sys/stat.h>#include <fcntl.h>#include <string.h>#include <errno.h>#include <unistd.h>#include <math.h>#define PLAYER_ENABLE_MSG 0#include "player.h"#include "error.h"#include "driver.h"#include "drivertable.h"#include "rmp_frame.h"#include "segwayrmp.h"// Number of RMP read cycles, without new speed commands from clients,// after which we'll stop the robot (for safety).  The read loop// seems to run at about 50Hz, or 20ms per cycle.#define RMP_TIMEOUT_CYCLES 20 // about 400ms////////////////////////////////////////////////////////////////////////////////// A factory creation functionDriver* SegwayRMP_Init(ConfigFile* cf, int section){  // Create and return a new instance of this driver  return ((Driver*) (new SegwayRMP(cf, section)));}////////////////////////////////////////////////////////////////////////////////// A driver registration function.void SegwayRMP_Register(DriverTable* table){  table->AddDriver("segwayrmp", SegwayRMP_Init);}////////////////////////////////////////////////////////////////////////////////// ConstructorSegwayRMP::SegwayRMP(ConfigFile* cf, int section)    : Driver(cf, section, true, PLAYER_MSGQUEUE_DEFAULT_MAXLEN){  memset(&this->position_id, 0, sizeof(player_devaddr_t));  memset(&this->position3d_id, 0, sizeof(player_devaddr_t));  memset(&this->power_id, 0, sizeof(player_devaddr_t));  // Do we create a position interface?  if(cf->ReadDeviceAddr(&(this->position_id), section, "provides",                       PLAYER_POSITION2D_CODE, -1, NULL) == 0)  {    if(this->AddInterface(this->position_id) != 0)    {      this->SetError(-1);          return;    }  }  // Do we create a position3d interface?  if(cf->ReadDeviceAddr(&(this->position3d_id), section, "provides",                         PLAYER_POSITION3D_CODE, -1, NULL) == 0)  {    if(this->AddInterface(this->position3d_id) != 0)    {      this->SetError(-1);          return;    }  }  // Do we create a power interface?  if(cf->ReadDeviceAddr(&(this->power_id), section, "provides",                         PLAYER_POWER_CODE, -1, NULL) == 0)  {    if(this->AddInterface(this->power_id) != 0)    {      this->SetError(-1);          return;    }  }  this->canio = NULL;  this->caniotype = cf->ReadString(section, "canio", "kvaser");  this->max_xspeed = (int) (1000 * cf->ReadLength(section, "max_xspeed", 0.5));  if(this->max_xspeed < 0)    this->max_xspeed = -this->max_xspeed;  this->max_yawspeed = (int) (RTOD(cf->ReadAngle(section, "max_yawspeed", 40)));  if(this->max_yawspeed < 0)    this->max_yawspeed = -this->max_yawspeed;    return;}SegwayRMP::~SegwayRMP(){  return;}intSegwayRMP::Setup(){  // Clear the command buffers#if 0  if (this->position_id.code)    ClearCommand(this->position_id);  if (this->position3d_id.code)    ClearCommand(this->position3d_id);#endif  PLAYER_MSG0(2, "CAN bus initializing");  if(!strcmp(this->caniotype, "kvaser"))    assert(this->canio = new CANIOKvaser);  else  {    PLAYER_ERROR1("Unknown CAN I/O type: \"%s\"", this->caniotype);    return(-1);  }  // start the CAN at 500 kpbs  if(this->canio->Init(BAUD_500K) < 0)   {    PLAYER_ERROR("error on CAN Init");    return(-1);  }  // Initialize odometry  this->odom_x = this->odom_y = this->odom_yaw = 0.0;  this->curr_xspeed = this->curr_yawspeed = 0.0;  this->motor_allow_enable = false;  this->motor_enabled = false;  this->firstread = true;  this->timeout_counter = 0;  this->StartThread();  return(0);}intSegwayRMP::Shutdown(){  PLAYER_MSG0(2, "Shutting down CAN bus");  fflush(stdout);    // TODO: segfaulting in here somewhere on client disconnect, but only   // sometimes.    //  // UPDATE: This might have been fixed by moving the call to StopThread()  // to before the sending of zero velocities.   There could have been  // a race condition, since Shutdown() is called from the server's thread   // context.  StopThread();    // send zero velocities, for some semblance of safety  CanPacket pkt;  MakeVelocityCommand(&pkt,0,0);  Write(pkt);  // shutdown the CAN  canio->Shutdown();  delete canio;  canio = NULL;    return(0);}// Main function for device thread.void SegwayRMP::Main(){  //unsigned char buffer[256];  //size_t buffer_len;  //player_position2d_cmd_t position_cmd;  //player_position3d_cmd_t position3d_cmd;  //void *client;  CanPacket pkt;  //int32_t xspeed,yawspeed;  //bool got_command;  bool first;  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);  pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);  first = true;    PLAYER_MSG0(2, "starting main loop");    for(;;)  {    pthread_testcancel();        // Read from the RMP    if(Read() < 0)    {      PLAYER_ERROR("Read() errored; bailing");      pthread_exit(NULL);    }    // Note that we got some data    if (first)    {      first = false;      PLAYER_MSG0(2, "got data from rmp");    }    // TODO: report better timestamps, possibly using time info from the RMP    // Send data to clients    Publish(this->position_id, NULL, PLAYER_MSGTYPE_DATA, PLAYER_POSITION2D_DATA_STATE,              &this->position_data, sizeof(this->position_data), NULL);    Publish(this->position3d_id, NULL, PLAYER_MSGTYPE_DATA, PLAYER_POSITION3D_DATA_STATE,              &this->position3d_data, sizeof(this->position3d_data), NULL);    Publish(this->power_id, NULL, PLAYER_MSGTYPE_DATA, PLAYER_POWER_DATA_STATE,              &this->power_data, sizeof(this->power_data), NULL);    /*    // check for config requests from the position interface    if((buffer_len = GetConfig(this->position_id, &client, buffer, sizeof(buffer),NULL)) > 0)    {      // if we write to the CAN bus as a result of the config, don't write      // a velocity command (may need to make this smarter if we get slow      // velocity control).      if(HandlePositionConfig(client,buffer,buffer_len) > 0)        continue;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -