peripherals  1.4.2
RoadNarrows Robotics Hardware Peripherals Package
MotRoboteqSmall.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: RoadNarrows Robotics Peripherals
4 //
5 // Library: libmot
6 //
7 // File:
8 // MotRoboteqSmall.cxx
9 //
10 /*! \file
11  *
12  * $LastChangedDate: 2013-09-24 09:34:42 -0600 (Tue, 24 Sep 2013) $
13  * $Rev: 3323 $
14  *
15  * \brief Common Human Interface Device Interface.
16  *
17  * \author: Robin Knight (robin.knight@roadnarrows.com)
18  * \author: Daniel Packard (daniel@roadnarrows.com)
19  * \author: Jessica Trujillo (jessica@roadnarrows.com)
20  * \author: Maurice Woods III (maurice@roadnarrows.com)
21  *
22  *
23  * \copyright
24  * \h_copy 2012-2017. RoadNarrows LLC.\n
25  * http://www.roadnarrows.com\n
26  * All Rights Reserved
27  */
28 // Permission is hereby granted, without written agreement and without
29 // license or royalty fees, to use, copy, modify, and distribute this
30 // software and its documentation for any purpose, provided that
31 // (1) The above copyright notice and the following two paragraphs
32 // appear in all copies of the source code and (2) redistributions
33 // including binaries reproduces these notices in the supporting
34 // documentation. Substantial modifications to this software may be
35 // copyrighted by their authors and need not follow the licensing terms
36 // described here, provided that the new terms are clearly indicated in
37 // all files where they apply.
38 //
39 // IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY MEMBERS/EMPLOYEES
40 // OF ROADNARROW LLC OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
41 // PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
42 // DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
43 // EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
44 // THE POSSIBILITY OF SUCH DAMAGE.
45 //
46 // THE AUTHOR AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
47 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
48 // FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
49 // "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
50 // PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
51 //
52 ////////////////////////////////////////////////////////////////////////////////
53 
54 
55 #include <vector>
56 #include <stdio.h>
57 #include <string.h>
58 #include <sstream>
59 #include "rnr/log.h"
60 #include "rnr/rnrconfig.h"
61 #include "rnr/units.h"
62 //#include "rnr/mot/MotRoboteq.h"
64 #include "rnr/serdev.h"
65 
66 using namespace rnr;
67 using namespace std;
68 
69 // DHP - Todo: move to libserial
70 int SerDevReadline(int fd, byte_t *buf, int timeout)
71 {
72  stringstream sstr;
73  char c;
74 
75  while ((c = (char)SerDevGetc(fd, timeout)) != '\r')
76  {
77  sstr << c;
78  }
79 
80  fprintf(stderr, "response received: %s\n", sstr.str().c_str());
81 
82  strcpy((char*)buf,sstr.str().c_str());
83 
84  return sstr.str().size();
85 }
86 
87 int MotRoboteqSmall::open(const string &devName, int baudRate)
88 {
89  LOGDIAG3("jnt devName= %s baudRate= %d \n", devName.c_str(), baudRate);
90  if ((m_fd=SerDevOpen(devName.c_str(),baudRate,8,'N',1,0,0))==-1)
91  {
92  fprintf(stderr, "dhp -here\n");
93  return -1;
94  }
95  fprintf(stderr, "dhp -here 2\n");
96  return 0;
97 }
98 
100 {
101  return SerDevClose(m_fd);
102 }
103 
104 // DHP - Move this to the base class
105 int MotRoboteqSmall::sendCommand(int fd, byte_t* buf, int nBytes, int timeout)
106 {
107  SerDevWrite(fd, buf, nBytes, timeout);
108  fprintf(stderr, "sent command: %s\n", buf);
109  return 0;
110 }
111 
112 // DHP - Move these to the base class
113 int MotRoboteqSmall::recvResponse(int fd, byte_t *buf, int timeout)
114 {
115  char c;
116  int nBytes=0;
117 
118  // DHP - need to add variable to check if echo is turned on
119  // if(m_bEchoIsOn)
120  {
121  // grab echo response
122  SerDevReadline(fd, buf, timeout);
123  }
124 
125  // grab actual response
126  nBytes = SerDevReadline(fd, buf, timeout);
127 
128  return nBytes;
129 }
130 
132 {
133  if (motID >2 || motID <1)
134  {
135  LOGDIAG3("Not a valid motor ID.\n");
136  return false;
137  }
138  return true;
139 }
140 
141 int MotRoboteqSmall::setSpeed(int motID, float speed, units_t units)
142 {
143  int rawSpeed;
144  if (!motIDIsValid(motID))
145  {
146  return -1;
147  }
148 
149  if (units == units_norm)
150  {
151  if (speed >1 || speed <-1)
152  {
153  LOGDIAG3("Not a valid normalized motor speed.\n");
154  return -1;
155  }
156  rawSpeed=(int)(speed*1000);
157  }
158 
159  return setSpeedRaw(motID, rawSpeed);
160 }
161 
162 int MotRoboteqSmall::setSpeed(VecSpeedTupples vecSpeedTupple, units_t units)
163 {
164  VecSpeedTupples::iterator iter;
165  VecSpeedRawTupples vecSpeedRawTupple;
166  for (iter=vecSpeedTupple.begin();iter!=vecSpeedTupple.end();iter++)
167  {
168  IDFloatTupple src = *iter;
169  IDIntTupple dest;
170  if (!motIDIsValid(src.m_nMotID))
171  {
172  return -1;
173  }
174  dest.m_nMotID = src.m_nMotID;
175  if (src.m_fVal >1 || src.m_fVal <-1)
176  {
177  LOGDIAG3("Not a valid normalized motor speed. \n");
178  return -1;
179  }
180  dest.m_nVal = (int)(1000 * src.m_fVal);
181  vecSpeedRawTupple.push_back(dest);
182  }
183  setSpeedRaw(vecSpeedRawTupple);
184  return -1;
185 }
186 
187 int MotRoboteqSmall::setSpeedRaw(int motID, int rawSpeed)
188 {
189  char cmd[32];
190  char res[32];
191 
192  sprintf(cmd,"!G %d %d\r", motID, rawSpeed);
193  int nBytes = strlen(cmd);
194 
195  sendCommand(m_fd, (byte_t*)cmd, nBytes, m_ntimeout);
196  nBytes = recvResponse(m_fd, (byte_t*)res, m_ntimeout);
197 
198  if(res[0] == '-')
199  {
200  LOGERROR("setSpeedRaw(id,speed) command failed.\n");
201  }
202 
203 }
204 
205 int MotRoboteqSmall::setSpeedRaw(VecSpeedRawTupples vecSpeedRawTupple)
206 {
207  stringstream str;
208  char buf[32];
209 
210  VecSpeedRawTupples::iterator iter;
211  for (iter=vecSpeedRawTupple.begin();iter!=vecSpeedRawTupple.end();iter++)
212  {
213  str << "!G " << (*iter).m_nMotID << " " << (*iter).m_nVal << "_";
214  }
215 
216  sendCommand(m_fd, (byte_t *)str.str().c_str(), str.str().length(), m_ntimeout);
217 
218  // check ALL responses
219  for( int i=0; i < vecSpeedRawTupple.size(); i++)
220  {
221  int nBytes = recvResponse(m_fd, (byte_t*)buf , m_ntimeout);
222 
223  // check (+/-)
224  if (buf[0] =='-')
225  {
226  LOGERROR("setSpeedRaw(vec) command failed\n");
227  return -1;
228  }
229  }
230 }
231 
232 int MotRoboteqSmall::stop(int motID)
233 {
234  setSpeedRaw(motID, 0);
235 }
236 
237 int MotRoboteqSmall::stop()
238 {
239  setSpeedRaw(1, 0);
240  setSpeedRaw(2, 0);
241 }
242 
244 {
245  setSpeedRaw(1, 0);
246  setSpeedRaw(2, 0);
247 
248  char buf[32];
249 
250  char cmd[32];
251  char res[32];
252  sprintf(cmd,"!EX\r");
253  int nBytes = strlen(cmd);
254 
255  sendCommand(m_fd, (byte_t*)cmd, nBytes, m_ntimeout);
256  recvResponse(m_fd, (byte_t*)res, m_ntimeout);
257  // check +/-
258  if (buf[0] =='-')
259  {
260  LOGERROR("setSpeedRaw(vec) command failed\nIs firmware updated?\n");
261  return -1;
262  }
263 }
264 
266 {
267  setSpeedRaw(1, 0);
268  setSpeedRaw(2, 0);
269 
270  char buf[32];
271 
272  char cmd[32];
273  char res[32];
274  sprintf(cmd,"!MG\r");
275  int nBytes = strlen(cmd);
276 
277  sendCommand(m_fd, (byte_t*)cmd, nBytes, m_ntimeout);
278  recvResponse(m_fd, (byte_t*)res, m_ntimeout);
279  // check +/-
280  if (buf[0] =='-')
281  {
282  LOGERROR("setSpeedRaw(vec) command failed\nIs firmware updated?\n");
283  return -1;
284  }
285 }
286 
287 int MotRoboteqSmall::getCurrent(int motID, units_t units)
288 {
289  if (!motIDIsValid(motID))
290  {
291  return -1;
292  }
293 
294  char cmd[32];
295  char res[32];
296  sprintf(cmd,"?A %d\r", motID);
297  int nBytes = strlen(cmd);
298 
299  sendCommand(m_fd, (byte_t *)cmd, nBytes, m_ntimeout);
300  recvResponse(m_fd, (byte_t *)res, m_ntimeout);
301 
302  // TODO : parse response
303 
304  return 0;
305 }
306 
308 {
309  char cmd[32];
310  char res[32];
311  sprintf(cmd,"~ALIM\r");
312  int nBytes = strlen(cmd);
313 
314  sendCommand(m_fd, (byte_t *)cmd, nBytes, m_ntimeout);
315  recvResponse(m_fd, (byte_t*)res, m_ntimeout);
316 
317  // TODO : parse response
318 
319  return 0;
320 }
321 
322 int MotRoboteqSmall::setCurrentLimits(int motID, int current, units_t units)
323 {
324  char buf[32];
325 
326  char cmd[32];
327  char res[32];
328  //todo: compare current argument to 75% of SDC2130 rating.
329  int rawCurrent = current *10;
330  sprintf(cmd,"^ALIM %d %d\r", motID, rawCurrent);
331  int nBytes = strlen(cmd);
332 
333  sendCommand(m_fd, (byte_t *)cmd, nBytes, m_ntimeout);
334  recvResponse(m_fd, (byte_t*)res, m_ntimeout);
335 
336  // check response +/-
337  if (buf[0] =='-')
338  {
339  LOGERROR("setSpeedRaw(vec) command failed\n");
340  return -1;
341  }
342 
343  return 0;
344 }
345 
347 {
348  char cmd[32];
349  char res[32];
350  sprintf(cmd,"~UVL_~OVL\r");
351  int nBytes = strlen(cmd);
352 
353  sendCommand(m_fd, (byte_t *)cmd, nBytes, m_ntimeout);
354 
355  recvResponse(m_fd,(byte_t *)res, m_ntimeout);
356  // TODO : parse response
357  recvResponse(m_fd,(byte_t *)res, m_ntimeout);
358  // TODO : parse response
359  return 0;
360 }
361 
363 {
364  char cmd[32];
365  char res[32];
366  sprintf(cmd,"?V\r");
367  int nBytes = strlen(cmd);
368 
369  sendCommand(m_fd, (byte_t *)cmd, nBytes, m_ntimeout);
370  recvResponse(m_fd,(byte_t *)res, m_ntimeout);
371 
372  // TODO : parse response
373  return 0;
374 }
375 
376 int MotRoboteqSmall::setVoltageLimits(int lowVoltage, int overVoltage)
377 {
378  if (lowVoltage < 5)
379  {
380  LOGDIAG3("Not a valid lower voltage limit. Must be greater than 5V \n");
381  return -1;
382  }
383 
384  int lowVoltageRaw=lowVoltage*10;
385  int overVoltageRaw=overVoltage*10;
386 
387  char buf[32];
388 
389  char cmd[32];
390  char res[32];
391  sprintf(cmd,"^UVL %d_^OVL %d\r", lowVoltageRaw, overVoltageRaw);
392  int nBytes = strlen(cmd);
393 
394  sendCommand(m_fd, (byte_t *)cmd, nBytes, m_ntimeout);
395  recvResponse(m_fd,(byte_t *)res, m_ntimeout);
396  // check +/-
397  if (buf[0] =='-')
398  {
399  LOGERROR("setSpeedRaw(vec) command failed\n");
400  return -1;
401  }
402  recvResponse(m_fd,(byte_t *)res, m_ntimeout);
403  // check +/-
404  if (buf[0] =='-')
405  {
406  LOGERROR("setSpeedRaw(vec) command failed\n");
407  return -1;
408  }
409 
410  return 0;
411 }
412 
413 // TODO : Check to ensure reversed motors aren't effected by accel/decel sign
414 int MotRoboteqSmall::setSpeedProfile(int motID, int accel, int decel)
415 {
416  if (decel==DEF_DEC)
417  {
418  decel=accel;
419  }
420 
421  char buf[32];
422 
423  char cmd[32];
424  char res[32];
425  sprintf(cmd,"^MAC %d %d_^MDEC %d %d\r", motID, accel, motID, decel);
426  int nBytes = strlen(cmd);
427 
428  sendCommand(m_fd, (byte_t *)cmd, nBytes, m_ntimeout);
429  recvResponse(m_fd,(byte_t *)res, m_ntimeout);
430  // check +/-
431  if (buf[0] =='-')
432  {
433  LOGERROR("setSpeedProfile() command failed\n");
434  return -1;
435  }
436  recvResponse(m_fd,(byte_t *)res, m_ntimeout);
437  // check +/-
438  if (buf[0] =='-')
439  {
440  LOGERROR("setSpeedProfile() command failed\n");
441  return -1;
442  }
443 
444  return 0;
445 
446 }
int setVoltageLimits(int lowVoltage, int overVoltage)
Function sets the minimum and maximum limits for applied voltage for all motors.
int eStop()
Function simultaneously halts motor rotation for all motors by setting speeds to zero.
int getCurrent(int motID, units_t units=units_amp)
Function retrieves value for current load on a single motor.
int eStopRelease()
Function releases emergency stop condition and allows normal ops.
int setSpeedProfile(int motID, int accel, int decel=DEF_DEC)
Function retrieves value for voltage applied to a single motor.
Common Human Interface Device Interface.
int setSpeed(int motID, float speed, units_t units=units_norm)
Description.
int setCurrentLimits(int motID, int current, units_t units=units_amp)
Function sets minimum and maximum limits for current.
int open(const std::string &devName, int baudRate)
Function opens serial communication with motor controller device.
bool motIDIsValid(int motID)
Function sends commands to the motor controller and receives responses from the motor controller...
int close()
Function closes serial communication with motor controller device.
int getVoltageLimits()
Function retrieves value for current load on a single motor.
RoadNarrows Robotics standard namespace.
Definition: HID.h:65
int getCurrentLimits()
Function determines if a motor controller can monitor current.
int getVoltage()
Function retrieves value for voltage applied to a single motor.