RoboteqDevice.cpp
Go to the documentation of this file.
00001 #include <iostream>
00002 #include <stdio.h>
00003 #include <string.h>
00004 #include <fcntl.h>
00005 #include <errno.h>
00006 #include <termios.h>
00007 #include <time.h>
00008 #include <sstream>
00009 
00010 #include "RoboteqDevice.h"
00011 #include "ErrorCodes.h"
00012 
00013 using namespace std;
00014 
00015 #define BUFFER_SIZE 1024
00016 #define MISSING_VALUE -1024
00017 
00018 RoboteqDevice::RoboteqDevice()
00019 {
00020         handle = RQ_INVALID_HANDLE;
00021 }
00022 RoboteqDevice::~RoboteqDevice()
00023 {
00024         Disconnect();
00025 }
00026 
00027 bool RoboteqDevice::IsConnected()
00028 {
00029         return handle != RQ_INVALID_HANDLE;
00030 }
00031 int RoboteqDevice::Connect(string port)
00032 {
00033         if(IsConnected())
00034         {
00035                 cout<<"Device is connected, attempting to disconnect."<<endl;
00036                 Disconnect();
00037         }
00038 
00039         //Open port.
00040         cout<<"Opening port: '"<<port<<"'...";
00041         handle = open(port.c_str(), O_RDWR |O_NOCTTY | O_NDELAY);
00042         if(handle == RQ_INVALID_HANDLE)
00043         {
00044                 cout<<"failed."<<endl;
00045                 return RQ_ERR_OPEN_PORT;
00046         }
00047 
00048         cout<<"succeeded."<<endl;
00049         fcntl (handle, F_SETFL, O_APPEND | O_NONBLOCK);
00050 
00051         cout<<"Initializing port...";
00052         InitPort();
00053         cout<<"...done."<<endl;
00054 
00055         int status;
00056         string response;
00057         cout<<"Detecting device version...";
00058         status = IssueCommand("?", "$1E", 10, response);
00059         if(status != RQ_SUCCESS)
00060         {
00061                 cout<<"failed (issue ?$1E response: "<<status<<")."<<endl;
00062                 Disconnect();
00063                 return RQ_UNRECOGNIZED_DEVICE;
00064         }
00065 
00066         if(response.length() < 12)
00067         {
00068                 cout<<"failed (unrecognized version)."<<endl;
00069                 Disconnect();
00070                 return RQ_UNRECOGNIZED_VERSION;
00071         }
00072 
00073         cout<<response.substr(8, 4)<<"."<<endl;
00074         return RQ_SUCCESS;
00075 }
00076 void RoboteqDevice::Disconnect()
00077 {
00078         if(IsConnected())
00079                 close(handle);
00080 
00081         handle = RQ_INVALID_HANDLE;
00082 }
00083 
00084 void RoboteqDevice::InitPort()
00085 {
00086         if(!IsConnected())
00087                 return;
00088 
00089         //Get the existing Comm Port Attributes in cwrget
00090         int BAUDRATE = B115200;
00091         struct termios newtio;
00092         tcgetattr (handle, &newtio);
00093 
00094         //Set the Tx and Rx Baud Rate to 115200
00095         cfsetospeed (&newtio, (speed_t)BAUDRATE);
00096         cfsetispeed (&newtio, (speed_t)BAUDRATE);
00097 
00098         //Enable the Receiver and  Set local Mode
00099         newtio.c_iflag = IGNBRK;                /* Ignore Break Condition & no processing under input options*/
00100         newtio.c_lflag = 0;                     /* Select the RAW Input Mode through Local options*/
00101         newtio.c_oflag = 0;                     /* Select the RAW Output Mode through Local options*/
00102         newtio.c_cflag |= (CLOCAL | CREAD);     /* Select the Local Mode & Enable Receiver through Control options*/
00103 
00104         //Set Data format to 7E1
00105         newtio.c_cflag &= ~CSIZE;               /* Mask the Character Size Bits through Control options*/
00106         newtio.c_cflag |= CS7;                  /* Select Character Size to 7-Bits through Control options*/
00107         newtio.c_cflag |= PARENB;               /* Select the Parity Enable through Control options*/
00108         newtio.c_cflag &= ~PARODD;              /* Select the Even Parity through Control options*/
00109 
00110         //cwrset.c_iflag |= (INPCK|ISTRIP);
00111         //cwrset.c_cc[VMIN] = 6;
00112 
00113         //Set the New Comm Port Attributes through cwrset
00114         tcsetattr (handle, TCSANOW, &newtio);   /* Set the attribute NOW without waiting for Data to Complete*/
00115 }
00116 
00117 int RoboteqDevice::Write(string str)
00118 {
00119         if(!IsConnected())
00120                 return RQ_ERR_NOT_CONNECTED;
00121 
00122         //cout<<"Writing: "<<ReplaceString(str.c_str(), "\r", "\r\n");
00123         int countSent = write(handle, str.c_str(), str.length());
00124 
00125         //Verify weather the Transmitting Data on UART was Successful or Not
00126         if(countSent < 0)
00127                 return RQ_ERR_TRANSMIT_FAILED;
00128 
00129         return RQ_SUCCESS;
00130 }
00131 int RoboteqDevice::ReadAll(string &str)
00132 {
00133         int countRcv;
00134         if(!IsConnected())
00135                 return RQ_ERR_NOT_CONNECTED;
00136 
00137         char buf[BUFFER_SIZE + 1] = "";
00138 
00139         str = "";
00140 //      int i = 0;
00141         while((countRcv = read(handle, buf, BUFFER_SIZE)) > 0)
00142         {
00143                 str.append(buf, countRcv);
00144 
00145                 //No further data.
00146                 if(countRcv < BUFFER_SIZE)
00147                         break;
00148         }
00149 
00150         if(countRcv < 0)
00151         {
00152                 if(errno == EAGAIN)
00153                         return RQ_ERR_SERIAL_IO;
00154                 else
00155                         return RQ_ERR_SERIAL_RECEIVE;
00156         }
00157 
00158         return RQ_SUCCESS;
00159 }
00160 
00161 int RoboteqDevice::IssueCommand(string commandType, string command, string args, int waitms, string &response, bool isplusminus)
00162 {
00163 
00164         int status;
00165         string read;
00166         response = "";
00167 
00168         if(args == "")
00169                 status = Write(commandType + command + "\r");
00170         else
00171                 status = Write(commandType + command + " " + args + "\r");
00172 
00173         if(status != RQ_SUCCESS)
00174                 return status;
00175 
00176         usleep(waitms * 1000l);
00177 
00178         status = ReadAll(read);
00179         if(status != RQ_SUCCESS)
00180                 return status;
00181 
00182         if(isplusminus)
00183         {
00184                 if(read.length() < 2)
00185                         return RQ_INVALID_RESPONSE;
00186 
00187                 response = read.substr(read.length() - 2, 1);
00188                 return RQ_SUCCESS;
00189         }
00190 
00191 
00192         string::size_type pos = read.rfind(command + "=");
00193         if(pos == string::npos)
00194                 return RQ_INVALID_RESPONSE;
00195 
00196         pos += command.length() + 1;
00197 
00198         string::size_type carriage = read.find("\r", pos);
00199         if(carriage == string::npos)
00200                 return RQ_INVALID_RESPONSE;
00201 
00202         response = read.substr(pos, carriage - pos);
00203 
00204         return RQ_SUCCESS;
00205 }
00206 int RoboteqDevice::IssueCommand(string commandType, string command, int waitms, string &response, bool isplusminus)
00207 {
00208         return IssueCommand(commandType, command, "", waitms, response, isplusminus);
00209 }
00210 
00211 int RoboteqDevice::SetConfig(int configItem, int index, int value)
00212 {
00213         string response;
00214         char command[10];
00215         char args[50];
00216 
00217         if(configItem < 0 || configItem > 255)
00218                 return RQ_INVALID_CONFIG_ITEM;
00219 
00220         sprintf(command, "$%02X", configItem);
00221         sprintf(args, "%i %i", index, value);
00222         if(index == MISSING_VALUE)
00223         {
00224                 sprintf(args, "%i", value);
00225                 index = 0;
00226         }
00227 
00228         if(index < 0)
00229                 return RQ_INDEX_OUT_RANGE;
00230 
00231         int status = IssueCommand("^", command, args, 10, response, true);
00232         if(status != RQ_SUCCESS)
00233                 return status;
00234         if(response != "+")
00235                 return RQ_SET_CONFIG_FAILED;
00236 
00237         return RQ_SUCCESS;
00238 }
00239 int RoboteqDevice::SetConfig(int configItem, int value)
00240 {
00241         return SetConfig(configItem, MISSING_VALUE, value);
00242 }
00243 
00244 int RoboteqDevice::SetCommand(int commandItem, int index, int value)
00245 {
00246         string response;
00247         char command[10];
00248         char args[50];
00249 
00250         if(commandItem < 0 || commandItem > 255)
00251                 return RQ_INVALID_COMMAND_ITEM;
00252 
00253         sprintf(command, "$%02X", commandItem);
00254         sprintf(args, "%i %i", index, value);
00255         if(index == MISSING_VALUE)
00256         {
00257                 if(value != MISSING_VALUE)
00258                         sprintf(args, "%i", value);
00259                 index = 0;
00260         }
00261 
00262         if(index < 0)
00263                 return RQ_INDEX_OUT_RANGE;
00264 
00265         int status = IssueCommand("!", command, args, 10, response, true);
00266         if(status != RQ_SUCCESS)
00267                 return status;
00268         if(response != "+")
00269                 return RQ_SET_COMMAND_FAILED;
00270 
00271         return RQ_SUCCESS;
00272 }
00273 int RoboteqDevice::SetCommand(int commandItem, int value)
00274 {
00275         return SetCommand(commandItem, MISSING_VALUE, value);
00276 }
00277 int RoboteqDevice::SetCommand(int commandItem)
00278 {
00279         return SetCommand(commandItem, MISSING_VALUE, MISSING_VALUE);
00280 }
00281 
00282 int RoboteqDevice::GetConfig(int configItem, int index, int &result)
00283 {
00284         string response;
00285         char command[10];
00286         char args[50];
00287 
00288         if(configItem < 0 || configItem > 255)
00289                 return RQ_INVALID_CONFIG_ITEM;
00290 
00291         if(index < 0)
00292                 return RQ_INDEX_OUT_RANGE;
00293 
00294         sprintf(command, "$%02X", configItem);
00295         sprintf(args, "%i", index);
00296 
00297         int status = IssueCommand("~", command, args, 10, response);
00298         if(status != RQ_SUCCESS)
00299                 return status;
00300 
00301         istringstream iss(response);
00302         iss>>result;
00303 
00304         if(iss.fail())
00305                 return RQ_GET_CONFIG_FAILED;
00306 
00307         return RQ_SUCCESS;
00308 }
00309 int RoboteqDevice::GetConfig(int configItem, int &result)
00310 {
00311         return GetConfig(configItem, 0, result);
00312 }
00313 
00314 int RoboteqDevice::GetValue(int operatingItem, int index, int &result)
00315 {
00316         string response;
00317         char command[10];
00318         char args[50];
00319 
00320         if(operatingItem < 0 || operatingItem > 255)
00321                 return RQ_INVALID_OPER_ITEM;
00322 
00323         if(index < 0)
00324                 return RQ_INDEX_OUT_RANGE;
00325 
00326         sprintf(command, "$%02X", operatingItem);
00327         sprintf(args, "%i", index);
00328 
00329         int status = IssueCommand("?", command, args, 10, response);
00330         if(status != RQ_SUCCESS)
00331                 return status;
00332 
00333         istringstream iss(response);
00334         iss>>result;
00335 
00336         if(iss.fail())
00337                 return RQ_GET_VALUE_FAILED;
00338 
00339         return RQ_SUCCESS;
00340 }
00341 int RoboteqDevice::GetValue(int operatingItem, int &result)
00342 {
00343         return GetValue(operatingItem, 0, result);
00344 }
00345 
00346 
00347 string ReplaceString(string source, string find, string replacement)
00348 {
00349         string::size_type pos = 0;
00350     while((pos = source.find(find, pos)) != string::npos)
00351         {
00352         source.replace(pos, find.size(), replacement);
00353         pos++;
00354     }
00355 
00356         return source;
00357 }
00358 
00359 void sleepms(int milliseconds)
00360 {
00361         usleep(milliseconds / 1000);
00362 }


komodo_rover
Author(s): RoboTiCan
autogenerated on Tue Jan 7 2014 11:20:12