Laelaps  2.3.5
RoadNarrows Robotics Small Outdoor Mobile Robot Project
RoboClaw.py
Go to the documentation of this file.
1 #
2 # Module: Laelaps.RoboClaw
3 #
4 # Package: RoadNarrows Laelaps Robotic Mobile Platform Package
5 #
6 # Link: https://github.com/roadnarrows-robotics/laelaps
7 #
8 # File: RoboClaw.py
9 #
10 ## \file
11 #
12 # \brief Python RoboClaw motor controller class and data.
13 #
14 # This code is based on the freely available python source from Ion Motion
15 # Control.
16 #
17 # \pkgsynopsis
18 # RoadNarrows Robotics \h_laelaps Small Mobile Robot Package
19 #
20 # \pkgfile{sw/pyModules/modules/Laelaps}
21 #
22 # \pkgauthor{Robin Knight,robin.knight@roadnarrows.com}
23 #
24 # \pkgcopyright{2015-2018,RoadNarrows LLC.,http://www.roadnarrows.com}
25 #
26 # @EulaBegin@
27 # Permission is hereby granted, without written agreement and without
28 # license or royalty fees, to use, copy, modify, and distribute this
29 # software and its documentation for any purpose, provided that
30 # (1) The above copyright notice and the following two paragraphs
31 # appear in all copies of the source code and (2) redistributions
32 # including binaries reproduces these notices in the supporting
33 # documentation. Substantial modifications to this software may be
34 # copyrighted by their authors and need not follow the licensing terms
35 # described here, provided that the new terms are clearly indicated in
36 # all files where they apply.
37 # \n\n
38 # IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY MEMBERS/EMPLOYEES
39 # OF ROADNARROW LLC OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
40 # PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
41 # DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
42 # EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
43 # THE POSSIBILITY OF SUCH DAMAGE.
44 # \n\n
45 # THE AUTHOR AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
46 # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
47 # FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
48 # "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
49 # PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
50 # @EulaEnd@
51 #
52 
53 import os
54 import sys
55 import serial
56 import struct
57 import time
58 
59 # Defines messages from swigged RoboClaw.h file.
60 from Laelaps.RoboClawMsgs import *
61 
62 """
63 Duplicate message interface prior to swig of header file.
64 
65 # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
66 # RoboClaw Addresses
67 # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
68 AddrMin = 0x80 ## minimum controller address
69 AddrMax = 0x87 ## maximum controller address
70 AddrDft = 0x80 ## default controller address
71 
72 # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
73 # RoboClaw Commands
74 # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
75 
76 # compatibility mode commands
77 CmdDriveForwardMot1 = 0 ## drive motor 1 forward
78 CmdDriveBackwardMot1 = 1 ## drive motor 1 backward
79 CmdSetMinMainVolt = 2 ## set main battery minimum voltage
80 CmdSetMaxMainVolt = 3 ## set main battery maximum voltage
81 CmdDriveForwardMot2 = 4 ## drive motor 1 forward
82 CmdDriveBackwardMot2 = 5 ## drive motor 2 backward
83 CmdDriveMot1 = 6 ## drive motor 1 forward/back (7-bit)
84 CmdDriveMot2 = 7 ## drive motor 2 foward/back (7-bit)
85 
86 # mix mode commands
87 CmdMixDriveForward = 8 ## drive motors forward
88 CmdMixDriveBackward = 9 ## drive motors backward
89 CmdMixTurnRight = 10 ## drive motors to turn right
90 CmdMixTurnLeft = 11 ## drive motors to turn left
91 CmdMixDrive = 12 ## drive motors foward/back (7-bit)
92 CmdMixTurn = 13 ## drive motors to turn R/L (7-bit)
93 
94 # advance commands
95 CmdReadEncoderMot1 = 16 ## read motor 1 encoder
96 CmdReadEncoderMot2 = 17 ## read motor 2 encoder
97 CmdReadSpeedMot1 = 18 ## read motor 1 speed (qpss)
98 CmdReadSpeedMot2 = 19 ## read motor 2 speed (qpss)
99 CmdResetEncoderRegs = 20 ## reset encoder registers (quadra)
100 CmdReadFwVersion = 21 ## read firmware version
101 CmdSetEncoderReg1 = 22 ## set encoder register 1 (quadrature)
102 CmdSetEncoderReg2 = 23 ## set encoder register 2 (quadrature)
103 CmdReadMainBattVolt = 24 ## read main battery voltage
104 CmdReadLogicVolt = 25 ## read logic battery voltage
105 CmdSetMinLogicVolt = 26 ## set logic battery minimum voltage
106 CmdSetMaxLogicVolt = 27 ## set logic battery maximum voltage
107 CmdSetVelPidMot1 = 28 ## set motor 1 velocity PID constants
108 CmdSetVelPidMot2 = 29 ## set motor 2 velocity PID constants
109 CmdRead125SpeedMot1 = 30 ## read motor 1 speed (pulses/125th sec)
110 CmdRead125SpeedMot2 = 31 ## read motor 2 speed (pulses/125th sec)
111 CmdDriveDutyMot1 = 32 ## drive motor 1 at duty cycle (no quad.)
112 CmdDriveDutyMot2 = 33 ## drive motor 2 at duty cycle (no quad.)
113 CmdDriveDuty = 34 ## drive motors at duty cycle (no quad.)
114 CmdDriveQMot1 = 35 ## drive motor 1 at quad. pulses/second
115 CmdDriveQMot2 = 36 ## drive motor 2 at quad. pulses/second
116 CmdDriveQ = 37 ## drive motors at quad. pulses/second
117 CmdDriveQAccelMot1 = 38 ## drive motor 1 at quad. pps with accel.
118 CmdDriveQAccelMot2 = 39 ## drive motor 2 at quad. pps with accel.
119 CmdDriveQAccel = 40 ## drive motors at quad. pps with accel.
120 CmdBufDriveQDistMot1 = 41 ## buffered drive motor 1 to dist at qpps
121 CmdBufDriveQDistMot2 = 42 ## buffered drive motor 2 to dist at qpps
122 CmdBufDriveQDist = 43 ## buffered drive motors to dist at qpps
123 CmdBufDriveQAccelDistMot1 = 44
124  ## buffered drive motor 1 to dist at qpps with accel.
125 CmdBufDriveQAccelDistMot2 = 45
126  ## buffered drive motor 2 to dist at qpps with accel.
127 CmdBufDriveQAccelDist = 46
128  ## buffered drive motors to dist at qpps with accel.
129 CmdReadBufLen = 47 ## read motors bufferd command length
130 
131 # more here...
132 
133 CmdReadMotorDraw = 49 ## read motors amp draw
134 CmdDriveQAccel2 = 50 ## drive motros at qpps with 2 accel vals
135 CmdBufDriveQAccel2Dist = 51
136  ## buffered drive motors to dist at qpps w/ 2 accel
137 # more here...
138 
139 CmdReadVelPidMot1 = 55 ## read motor 1 velocity PID constants
140 CmdReadVelPidMot2 = 56 ## read motor 2 velocity PID constants
141 CmdSetMainBattCutoffs = 57 ## set main battery voltage cutoffs
142 CmdSetLogicCutoffs = 58 ## set logic voltage cutoffs
143 CmdReadMainBattCutoffs = 59 ## read main battery cutoff settings
144 CmdReadLogicCutoffs = 60 ## read logic voltage cutoff settings
145 CmdSetPosPidMot1 = 61 ## set motor 1 position PID constants
146 CmdSetPosPidMot2 = 62 ## set motor 2 position PID constants
147 CmdReadPosPidMot1 = 63 ## read motor 1 position PID constants
148 CmdReadPosPidMot2 = 64 ## read motor 2 position PID constants
149 CmdBufDriveQProfPosMot1 = 65
150  ## drive motor 1 with signed qpps, accel, deccel and position
151 CmdBufDriveQProfPosMot2 = 66
152  ## drive motor 2 with signed qpps, accel, deccel and position
153 CmdBufDriveQProfPos = 67
154  ## drive motors with signed qpps, accel, deccel and position
155 
156 # more here...
157 
158 CmdReadTemp = 82 ## read board temperature
159 CmdReadTemp2 = 83 ## read board second temperature
160 CmdReadStatus = 90 ## read current board status
161 CmdReadEncoderMode = 91 ## read encoder mode for both motors
162 CmdSetEncoderModeMot1 = 92 ## set motor 1 encoder mode
163 CmdSetEncoderModeMot2 = 93 ## set motor 2 encoder mode
164 CmdWriteEEPROM = 94 ## write settings to EEPROM
165 
166 # more here...
167 
168 # Note: RoboClass User Manual v5 error. The Cmd*MaxCurrentMotn command numbers
169 # are shifted down by 1.
170 CmdSetMaxCurrentMot1 = 133 ## set motor 1 maximum current limit
171 CmdSetMaxCurrentMot2 = 134 ## set motor 2 maximum current limit
172 CmdReadMaxCurrentMot1 = 135 ## read motor 1 maximum current limit
173 CmdReadMaxCurrentMot2 = 136 ## read motor 2 maximum current limit
174 
175 
176 # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
177 # RoboClaw Packet Checksum - Deprecated
178 # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
179 CheckSumMask = 0x7f ## checksum 7-bit mask
180 AckReqBit = 0x80 ## request ack to write commands
181 
182 # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
183 # RoboClaw Packet CRC
184 # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
185 
186 # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
187 # RoboClaw Responses
188 # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
189 RspAck = 0xff ## ack response to write commands
190 
191 # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
192 # RoboClaw Message Parameters
193 # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
194 
195 ParamVelPidQppsDft = 44000 ## default qpps max speed
196 ParamVelPidPDft = 0x00010000 ## default vel proportional const
197 ParamVelPidIDft = 0x00008000 ## default vel integrative const
198 ParamVelPidDDft = 0x00004000 ## default vel derivative const
199 ParamVelPidCvt = 0x00010000 ## vel PID conversion
200 
201 ParamAmpScale = 0.01 ## value * s = amps
202 ParamAmpMin = 0.0 ## minimum amps
203 ParamAmpMax = 15.0 ## maximum amps
204 
205 Duplicate interface end
206 """
207 
208 
209 # ------------------------------------------------------------------------------
210 # RoboClawException Class
211 # ------------------------------------------------------------------------------
212 
213 ##
214 ## \brief RoboClaw exception class.
215 ##
216 class RoboClawException(Exception):
217  ##
218  ## \brief Constructor.
219  ##
220  ## \param msg Error message string.
221  ##
222  def __init__(self, msg):
223  ## error message attribute
224  self.message = 'Roboclaw: ' + msg
225 
226  def __repr__(self):
227  return "RoboClawException(%s)" % (repr(self.message))
228 
229  def __str__(self):
230  return self.message
231 
232 
233 #-------------------------------------------------------------------------------
234 # RoboClaw Class
235 #-------------------------------------------------------------------------------
236 
237 ##
238 ## \brief RobotClaw Motor Controller class.
239 ##
240 class RoboClaw:
241 
242  #
243  ## \brief Constructor.
244  #
245  def __init__(self):
246  self.m_checksum = 0 ## checksum (deprecated)
247  self.m_port = None ## serial port
248  self.m_addrLast = 0 ## last address
249  self.m_fnChipSelect = self.noop ## board chip select
250  self.m_isOpen = False ## port is [not] open
251 
252  #
253  ## \brief Open connection to motor controller(s).
254  ##
255  ## \param device Serial device name.
256  ## \param baudrate Serial baud rate.
257  ## \param fnChipSelect Motor controller selection function.
258  #
259  def open(self, device, baudrate, fnChipSelect=None):
260  try:
261  self.m_port = serial.Serial(device, baudrate=baudrate, timeout=0.5)
262  except serial.SerialException as inst:
263  raise RoboClawException(inst.message)
264  self.m_port.flushInput()
265  self.m_port.flushOutput()
266  self.m_checksum = 0
267  self.m_addrLast = 0
268  if fnChipSelect is None:
269  self.m_fnChipSelect = self.noop
270  else:
271  self.m_fnChipSelect = fnChipSelect
272  self.m_isOpen = True
273 
274  def close(self):
275  self.m_port.close()
276  self.m_isOpen = False
277 
278  def isOpen(self):
279  return self.m_isOpen
280 
281  def noop(self, port, addrSel, addrLast):
282  pass
283 
284 
285  # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
286  # Firmware Versions >= 4.1.11
287  # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
288 
289  #
290  ## \brief Execute command with acknowledgement response.
291  ##
292  ## Command: addr cmdId [data] [crc16]
293  ## Response: ack
294  ##
295  #
296  def execCmdWithAckRsp(self, addr, cmdId, sCmdData, appendCrc = False):
297  sCmd = chr(addr) + chr(cmdId) + sCmdData
298  crcCmd = self.crc16(0, sCmd)
299  if appendCrc:
300  sCmd += self.packU16(crcCmd)
301  try:
302  self.m_port.write(sCmd)
303  except (serial.SerialException, serial.SerialTimeoutException) as inst:
304  raise RoboClawException(inst.message)
305  try:
306  sRsp = self.m_port.read(1)
307  except (serial.SerialException, serial.SerialTimeoutException) as inst:
308  raise RoboClawException(inst.message)
309  if len(sRsp) < 1:
310  raise RoboClawException("Command %u: Received no ack" % (cmdId))
311  else:
312  ack = self.unpackU8(sRsp)
313  if ack != RspAck:
314  raise RoboClawException("Command %u: Received bad ack 0x%02x" % \
315  (cmdId, ack))
316 
317  #
318  ## \brief Execute command with data response.
319  ##
320  ## Command: addr cmdId [data...] [crc16]
321  ## Response: data... crc16
322  ##
323  #
324  def execCmdWithDataRsp(self, addr, cmdId, sCmdData, lenRsp, appendCrc=False):
325  sCmd = chr(addr) + chr(cmdId) + sCmdData
326  crcCmd = self.crc16(0, sCmd)
327  if appendCrc:
328  sCmd += packU16(crcCmd)
329  try:
330  self.m_port.write(sCmd)
331  except (serial.SerialException, serial.SerialTimeoutException) as inst:
332  raise RoboClawException(inst.message)
333  try:
334  sRsp = self.m_port.read(lenRsp)
335  except (serial.SerialException, serial.SerialTimeoutException) as inst:
336  raise RoboClawException(inst.message)
337  if len(sRsp) != lenRsp:
338  raise RoboClawException("Command %u: Partial response: " \
339  "Expected %d bytes, received %d bytes" % (cmdId, lenRsp, len(sRsp)))
340  if len(sRsp) >= 2:
341  crcRsp = self.unpackU16(sRsp[-2:])
342  sRsp = sRsp[:-2]
343  else:
344  crcRsp = 0
345  crcCalc = self.crc16(crcCmd, sRsp)
346  if crcRsp != crcCalc:
347  raise RoboClawException("Command %u: CRC mismatch: " \
348  "Expected 0x%04x, received 0x%04x" % (cmdId, crcCalc, crcRsp))
349  return sRsp
350 
351  def packU8(self, val):
352  return struct.pack('>B', val)
353 
354  def packS8(self, val):
355  return struct.pack('>b',val)
356 
357  def packU16(self, val):
358  return struct.pack('>H',val)
359 
360  def packS16(self, val):
361  return struct.pack('>h',val)
362 
363  def packU32(self, val):
364  return struct.pack('>L',val)
365 
366  def packS32(self, val):
367  return struct.pack('>l',val)
368 
369  def unpackU8(self, s):
370  return struct.unpack('>B', s[:1])[0]
371 
372  def unpackS8(self, s):
373  return struct.unpack('>b', s[:1])[0]
374 
375  def unpackU16(self, s):
376  return struct.unpack('>H', s[:2])[0]
377 
378  def unpackS16(self, s):
379  return struct.unpack('>h', s[:2])[0]
380 
381  def unpackU32(self, s):
382  return struct.unpack('>L', s[:4])[0]
383 
384  def unpackS32(self, s):
385  return struct.unpack('>l', s[:4])[0]
386 
387  def crc16(self, crc, buf):
388  for b in buf:
389  crc = crc ^ (ord(b) << 8);
390  for bit in range(0,8):
391  if crc & 0x8000:
392  crc = (crc << 1) ^ 0x1021;
393  else:
394  crc = crc << 1;
395  return crc & 0xffff;
396 
397 
398  # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
399  # Firmware Versions < 4.1.11 Deprecated
400  # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
401 
402  def sendCmdHdr(self, addr, command):
403  raise RoboClaw("sendCmdHdr: Deprecated");
404  self.m_fnChipSelect(self.m_port, addr, self.m_addrLast)
405  self.m_checksum = addr
406  self.m_checksum += command
407  try:
408  self.m_port.write(chr(addr))
409  self.m_port.write(chr(command))
410  except (serial.SerialException, serial.SerialTimeoutException) as inst:
411  raise RoboClawException(inst.message)
412  except struct.error as inst:
413  raise RoboClawException(inst.message)
414  self.m_addrLast = addr
415 
416  def readU8(self):
417  try:
418  val = struct.unpack('>B',self.m_port.read(1))
419  except (serial.SerialException, serial.SerialTimeoutException) as inst:
420  raise RoboClawException(inst.message)
421  except struct.error as inst:
422  raise RoboClawException(inst.message)
423  self.m_checksum += val[0]
424  return val[0]
425 
426  def readS8(self):
427  try:
428  val = struct.unpack('>b',self.m_port.read(1))
429  except (serial.SerialException, serial.SerialTimeoutException) as inst:
430  raise RoboClawException(inst.message)
431  except struct.error as inst:
432  raise RoboClawException(inst.message)
433  self.m_checksum += val[0]
434  return val[0]
435 
436  def readU16(self):
437  try:
438  val = struct.unpack('>H',self.m_port.read(2))
439  except (serial.SerialException, serial.SerialTimeoutException) as inst:
440  raise RoboClawException(inst.message)
441  except struct.error as inst:
442  raise RoboClawException(inst.message)
443  self.m_checksum += (val[0]&0xFF)
444  self.m_checksum += (val[0]>>8)&0xFF
445  return val[0]
446 
447  def readS16(self):
448  try:
449  val = struct.unpack('>h',self.m_port.read(2))
450  except (serial.SerialException, serial.SerialTimeoutException) as inst:
451  raise RoboClawException(inst.message)
452  except struct.error as inst:
453  raise RoboClawException(inst.message)
454  self.m_checksum += val[0]
455  self.m_checksum += (val[0]>>8)&0xFF
456  return val[0]
457 
458  def readU32(self):
459  try:
460  val = struct.unpack('>L',self.m_port.read(4))
461  except (serial.SerialException, serial.SerialTimeoutException) as inst:
462  raise RoboClawException(inst.message)
463  except struct.error as inst:
464  raise RoboClawException(inst.message)
465  self.m_checksum += val[0]
466  self.m_checksum += (val[0]>>8)&0xFF
467  self.m_checksum += (val[0]>>16)&0xFF
468  self.m_checksum += (val[0]>>24)&0xFF
469  return val[0]
470 
471  def readS32(self):
472  try:
473  val = struct.unpack('>l',self.m_port.read(4))
474  except (serial.SerialException, serial.SerialTimeoutException) as inst:
475  raise RoboClawException(inst.message)
476  except struct.error as inst:
477  raise RoboClawException(inst.message)
478  self.m_checksum += val[0]
479  self.m_checksum += (val[0]>>8)&0xFF
480  self.m_checksum += (val[0]>>16)&0xFF
481  self.m_checksum += (val[0]>>24)&0xFF
482  return val[0]
483 
484  def writeU8(self, val):
485  self.m_checksum += val
486  try:
487  return self.m_port.write(struct.pack('>B',val))
488  except (serial.SerialException, serial.SerialTimeoutException) as inst:
489  raise RoboClawException(inst.message)
490  except struct.error as inst:
491  raise RoboClawException(inst.message)
492 
493  def writeS8(self, val):
494  self.m_checksum += val
495  try:
496  return self.m_port.write(struct.pack('>b',val))
497  except (serial.SerialException, serial.SerialTimeoutException) as inst:
498  raise RoboClawException(inst.message)
499  except struct.error as inst:
500  raise RoboClawException(inst.message)
501 
502  def writeU16(self, val):
503  self.m_checksum += val
504  self.m_checksum += (val>>8)&0xFF
505  try:
506  return self.m_port.write(struct.pack('>H',val))
507  except (serial.SerialException, serial.SerialTimeoutException) as inst:
508  raise RoboClawException(inst.message)
509  except struct.error as inst:
510  raise RoboClawException(inst.message)
511 
512  def writeS16(self, val):
513  self.m_checksum += val
514  self.m_checksum += (val>>8)&0xFF
515  try:
516  return self.m_port.write(struct.pack('>h',val))
517  except (serial.SerialException, serial.SerialTimeoutException) as inst:
518  raise RoboClawException(inst.message)
519  except struct.error as inst:
520  raise RoboClawException(inst.message)
521 
522  def writeU32(self, val):
523  self.m_checksum += val
524  self.m_checksum += (val>>8)&0xFF
525  self.m_checksum += (val>>16)&0xFF
526  self.m_checksum += (val>>24)&0xFF
527  try:
528  return self.m_port.write(struct.pack('>L',val))
529  except (serial.SerialException, serial.SerialTimeoutException) as inst:
530  raise RoboClawException(inst.message)
531  except struct.error as inst:
532  raise RoboClawException(inst.message)
533 
534  def writeS32(self, val):
535  self.m_checksum += val
536  self.m_checksum += (val>>8)&0xFF
537  self.m_checksum += (val>>16)&0xFF
538  self.m_checksum += (val>>24)&0xFF
539  try:
540  return self.m_port.write(struct.pack('>l',val))
541  except (serial.SerialException, serial.SerialTimeoutException) as inst:
542  raise RoboClawException(inst.message)
543  except struct.error as inst:
544  raise RoboClawException(inst.message)
545 
546 
547  # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
548  # Firmware Versions >= 4.1.11
549  # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
550 
551  ## Command: 0
552  def M1Forward(self, addr, val):
553  self.execCmdWithAckRsp(addr, CmdDriveForwardMot1, self.packU8(val), True)
554 
555  ## Command: 1
556  def M1Backward(self, addr, val):
557  self.execCmdWithAckRsp(addr, CmdDriveBackwardMot1, self.packU8(val), True)
558 
559  ## Command: 2
560  def setMinMainBattery(self, addr, val):
561  self.execCmdWithAckRsp(addr, CmdSetMinMainVolt, self.packU8(val), True)
562 
563  ## Command: 3
564  def setMaxMainBattery(self, addr, val):
565  self.execCmdWithAckRsp(addr, CmdSetMaxMainVolt, self.packU8(val), True)
566 
567  ## Command: 4
568  def M2Forward(self, addr, val):
569  self.execCmdWithAckRsp(addr, CmdDriveForwardMot2, self.packU8(val), True)
570 
571  ## Command: 5
572  def M2Backward(self, addr, val):
573  self.execCmdWithAckRsp(addr, CmdDriveBackwardMot2, self.packU8(val), True)
574 
575  ## Command: 6
576  def DriveM1(self, addr, val):
577  self.execCmdWithAckRsp(addr, CmdDriveMot1, self.packU8(val), True)
578 
579  ## Command: 7
580  def DriveM2(self, addr, val):
581  self.execCmdWithAckRsp(addr, CmdDriveMot2, self.packU8(val), True)
582 
583  ## Command: 8
584  def ForwardMixed(self, addr, val):
585  self.execCmdWithAckRsp(addr, CmdMixDriveForward, self.packU8(val), True)
586 
587  ## Command: 9
588  def BackwardMixed(self, addr, val):
589  self.execCmdWithAckRsp(addr, CmdMixDriveBackward, self.packU8(val), True)
590 
591  ## Command: 10
592  def RightMixed(self, addr, val):
593  self.execCmdWithAckRsp(addr, CmdMixTurnRight, self.packU8(val), True)
594 
595  ## Command: 11
596  def LeftMixed(self, addr, val):
597  self.execCmdWithAckRsp(addr, CmdMixTurnLeft, self.packU8(val), True)
598 
599  ## Command: 12
600  def DriveMixed(self, addr, val):
601  self.execCmdWithAckRsp(addr, CmdMixDrive, self.packU8(val), True)
602 
603  ## Command: 13
604  def TurnMixed(self, addr, val):
605  self.execCmdWithAckRsp(addr, CmdMixTurn, self.packU8(val), True)
606 
607  ## Command: 16
608  def readM1Encoder(self, addr):
609  sRsp = self.execCmdWithDataRsp(addr, CmdReadEncoderMot1, '', 7)
610  enc = self.unpackU32(sRsp)
611  status = self.unpackU8(sRsp[4:])
612  return (enc,status)
613 
614  ## Command: 17
615  def readM2Encoder(self, addr):
616  sRsp = self.execCmdWithDataRsp(addr, CmdReadEncoderMot2, '', 7)
617  enc = self.unpackU32(sRsp)
618  status = self.unpackU8(sRsp[4:])
619  return (enc,status)
620 
621  ## Command: 18
622  def readM1Speed(self, addr):
623  sRsp = self.execCmdWithDataRsp(addr, CmdReadSpeedMot1, '', 7)
624  speed = self.unpackU32(sRsp)
625  status = self.unpackU8(sRsp[4:])
626  return (speed, status)
627 
628  ## Command: 19
629  def readM2Speed(self, addr):
630  sRsp = self.execCmdWithDataRsp(addr, CmdReadSpeedMot2, '', 7)
631  speed = self.unpackU32(sRsp)
632  status = self.unpackU8(sRsp[4:])
633  return (speed, status)
634 
635  ## Command: 20
636  def resetEncoderCnts(self, addr):
637  self.execCmdWithAckRsp(addr, CmdResetEncoderCntrs, '', True)
638 
639  ## Command: 21
640  def readVersion(self, addr):
641  sCmd = chr(addr) + chr(CmdReadFwVersion)
642  crcCmd = self.crc16(0, sCmd)
643  try:
644  self.m_port.write(sCmd)
645  except (serial.SerialException, serial.SerialTimeoutException) as inst:
646  raise RoboClawException(inst.message)
647  try:
648  sRsp = self.m_port.read(48) # max bytes, can be less
649  except serial.SerialException as inst:
650  raise RoboClawException(inst.message)
651  except serial.SerialTimeoutException:
652  pass
653  if len(sRsp) >= 2:
654  crcRsp = self.unpackU16(sRsp[-2:])
655  sRsp = sRsp[:-2]
656  else:
657  crcRsp = 0
658  crcCalc = self.crc16(crcCmd, sRsp)
659  if crcRsp != crcCalc:
660  raise RoboClawException("Command %u: CRC mismatch: " \
661  "Expected 0x%04x, received 0x%04x" % (sCmd[1], crcCalc, crcRsp))
662  else:
663  sVer = sRsp[:-2] # strip ending NL+0
664  return sVer
665 
666  ## Command: 24
667  def readMainBattery(self, addr):
668  sRsp = self.execCmdWithDataRsp(addr, CmdReadMainBattVolt, '', 4)
669  return self.unpackU16(sRsp);
670 
671  ## Command: 25
672  def readLogicBattery(self, addr):
673  sRsp = self.execCmdWithDataRsp(addr, CmdReadLogicVolt, '', 4)
674  return self.unpackU16(sRsp);
675 
676  ## Command: 28
677  def setM1Pidq(self, addr, p, i, d, qpps):
678  sData = ''
679  sData += self.packU32(d)
680  sData += self.packU32(p)
681  sData += self.packU32(i)
682  sData += self.packU32(qpps)
683  self.execCmdWithAckRsp(addr, CmdSetVelPidMot1, sData, True)
684 
685  ## Command: 29
686  def setM2Pidq(self, addr, p, i, d, qpps):
687  sData = ''
688  sData += self.packU32(d)
689  sData += self.packU32(p)
690  sData += self.packU32(i)
691  sData += self.packU32(qpps)
692  self.execCmdWithAckRsp(addr, CmdSetVelPidMot2, sData, True)
693 
694  ## Command: 30
695  def readM1instspeed(self, addr):
696  sRsp = self.execCmdWithDataRsp(addr, CmdRead125SpeedMot1, '', 7)
697  speed = self.unpackU32(sRsp)
698  status = self.unpackU8(sRsp[4:])
699  return (speed,status)
700 
701  ## Command: 31
702  def readM2instspeed(self, addr):
703  sRsp = self.execCmdWithDataRsp(addr, CmdRead125SpeedMot2, '', 7)
704  speed = self.unpackU32(sRsp)
705  status = self.unpackU8(sRsp[4:])
706  return (speed,status)
707 
708  ## Command: 32
709  def setM1Duty(self, addr, val):
710  self.execCmdWithAckRsp(addr, CmdDriveDutyMot1, self.packS16(val), True)
711 
712  ## Command: 33
713  def setM2Duty(self, addr, val):
714  self.execCmdWithAckRsp(addr, CmdDriveDutyMot2, self.packS16(val), True)
715 
716  ## Command: 34
717  def setMixedDuty(self, addr, m1, m2):
718  sData = ''
719  sData += self.packS16(m1)
720  sData += self.packS16(m2)
721  self.execCmdWithAckRsp(addr, CmdDriveDuty, sData, True)
722 
723  ## Command: 35
724  def setM1Speed(self, addr, val):
725  self.execCmdWithAckRsp(addr, CmdDriveQMot1, self.packS32(val), True)
726 
727  ## Command: 36
728  def setM2Speed(self, addr, val):
729  self.execCmdWithAckRsp(addr, CmdDriveQMot2, self.packS32(val), True)
730 
731  ## Command: 37
732  def setMixedSpeed(self, addr, m1, m2):
733  sData = ''
734  sData += self.packS32(m1)
735  sData += self.packS32(m2)
736  self.execCmdWithAckRsp(addr, CmdDriveQ, sData, True)
737 
738  ## Command: 38
739  def setM1SpeedAccel(self, addr, accel,speed):
740  sData = ''
741  sData += self.packU32(accel)
742  sData += self.packS32(speed)
743  self.execCmdWithAckRsp(addr, CmdDriveQAccelMot1, sData, True)
744 
745  ## Command: 39
746  def setM2SpeedAccel(self, addr, accel, speed):
747  sData = ''
748  sData += self.packU32(accel)
749  sData += self.packS32(speed)
750  self.execCmdWithAckRsp(addr, CmdDriveQAccelMot2, sData, True)
751 
752  ## Command: 40
753  def setMixedSpeedAccel(self, addr, accel, speed1, speed2):
754  sData = ''
755  sData += self.packU32(accel)
756  sData += self.packS32(speed1)
757  sData += self.packS32(speed2)
758  self.execCmdWithAckRsp(addr, CmdDriveQAccel, sData, True)
759 
760  ## Command: 41
761  def setM1SpeedDistance(self, addr, speed, distance, buffered):
762  sData = ''
763  sData += self.packS32(speed)
764  sData += self.packU32(distance)
765  sData += self.packU8(buffered)
766  self.execCmdWithAckRsp(addr, CmdBufDriveQDistMot1, sData, True)
767 
768  ## Command: 42
769  def setM2SpeedDistance(self, addr, speed, distance, buffered):
770  sData = ''
771  sData += self.packS32(speed)
772  sData += self.packU32(distance)
773  sData += self.packU8(buffered)
774  self.execCmdWithAckRsp(addr, CmdBufDriveQDistMot2, sData, True)
775 
776  ## Command: 43
777  def setMixedSpeedDistance(self, addr, speed1, distance1, speed2, distance2,
778  buffered):
779  sData = ''
780  sData += self.packS32(speed1)
781  sData += self.packU32(distance1)
782  sData += self.packS32(speed2)
783  sData += self.packU32(distance2)
784  sData += self.packU8(buffered)
785  self.execCmdWithAckRsp(addr, CmdBufDriveQDist, sData, True)
786 
787  ## Command: 44
788  def setM1SpeedAccelDistance(self, addr, accel, speed, distance, buffered):
789  sData = ''
790  sData += self.packU32(accel)
791  sData += self.packS32(speed)
792  sData += self.packU32(distance)
793  sData += self.packU8(buffered)
794  self.execCmdWithAckRsp(addr, CmdBufDriveQAccelDistMot1, sData, True)
795 
796  ## Command: 45
797  def setM2SpeedAccelDistance(self, addr, accel, speed, distance, buffered):
798  sData = ''
799  sData += self.packU32(accel)
800  sData += self.packS32(speed)
801  sData += self.packU32(distance)
802  sData += self.packU8(buffered)
803  self.execCmdWithAckRsp(addr, CmdBufDriveQAccelDistMot2, sData, True)
804 
805  ## Command: 46
806  def setMixedSpeedAccelDistance(self, addr, accel, speed1, distance1,
807  speed2, distance2,
808  buffered):
809  sData = ''
810  sData += self.packU32(accel)
811  sData += self.packS32(speed1)
812  sData += self.packU32(distance1)
813  sData += self.packS32(speed2)
814  sData += self.packU32(distance2)
815  sData += self.packU8(buffered)
816  self.execCmdWithAckRsp(addr, CmdBufDriveQAccelDist, sData, True)
817 
818  ## Command: 47
819  def readBufferCnts(self, addr):
820  sRsp = self.execCmdWithDataRsp(addr, CmdReadBufLen, '', 4)
821  buffer1 = self.unpackU8(sRsp)
822  buffer2 = self.unpackU8(sRsp[1:])
823  return (buffer1,buffer2)
824 
825  ## Command: 49
826  ## Note: RoboClaw User Manual v5 error. Values are signed 16 bits.
827  def readCurrents(self, addr):
828  sRsp = self.execCmdWithDataRsp(addr, CmdReadMotorDraw, '', 6)
829  amp1 = self.unpackU16(sRsp)
830  amp2 = self.unpackU16(sRsp[2:])
831  if amp1 & 0x8000:
832  amp1 -= 0x10000
833  if amp2 & 0x8000:
834  amp2 -= 0x10000
835  return (amp1,amp2)
836 
837  ## Command: 50
838  def setMixedSpeedIAccel(self, addr, accel1, speed1, accel2, speed2):
839  sData = ''
840  sData += self.packU32(accel1)
841  sData += self.packS32(speed1)
842  sData += self.packU32(accel2)
843  sData += self.packS32(speed2)
844  self.execCmdWithAckRsp(addr, CmdDriveQAccel2, sData, True)
845 
846  ## Command: 51
847  def setMixedSpeedIAccelDistance(self, addr, accel1, speed1, distance1,
848  accel2, speed2, distance2,
849  buffered):
850  sData = ''
851  sData += self.packU32(accel1)
852  sData += self.packS32(speed1)
853  sData += self.packU32(distance1)
854  sData += self.packU32(accel2)
855  sData += self.packS32(speed2)
856  sData += self.packU32(distance2)
857  sData += self.packU8(buffered)
858  self.execCmdWithAckRsp(addr, CmdBufDriveQAccel2Dist, sData, True)
859 
860  ## Command: 52
861  def setM1DutyAccel(self, addr, accel, duty):
862  sData = ''
863  sData += self.packS16(duty)
864  sData += self.packU16(accel)
865  self.execCmdWithAckRsp(addr, 52, sData, True)
866 
867  ## Command: 53
868  def setM2DutyAccel(self, addr, accel, duty):
869  sData = ''
870  sData += self.packS16(duty)
871  sData += self.packU16(accel)
872  self.execCmdWithAckRsp(addr, 53, sData, True)
873 
874  ## Command: 54
875  def setMixedDutyAccel(self, addr, accel1, duty1, accel2, duty2):
876  sData = ''
877  sData += self.packS16(duty1)
878  sData += self.packU16(accel1)
879  sData += self.packS16(duty2)
880  sData += self.packU16(accel2)
881  self.execCmdWithAckRsp(addr, 54, sData, True)
882 
883  ## Command: 55
884  def readM1Pidq(self, addr):
885  sRsp = self.execCmdWithDataRsp(addr, CmdReadVelPidMot1, '', 18)
886  p = self.unpackU32(sRsp)
887  i = self.unpackU32(sRsp[4:])
888  d = self.unpackU32(sRsp[8:])
889  qpps = self.unpackU32(sRsp[12:])
890  return (p,i,d,qpps)
891 
892  ## Command: 56
893  def readM2Pidq(self, addr):
894  sRsp = self.execCmdWithDataRsp(addr, CmdReadVelPidMot2, '', 18)
895  p = self.unpackU32(sRsp)
896  i = self.unpackU32(sRsp[4:])
897  d = self.unpackU32(sRsp[8:])
898  qpps = self.unpackU32(sRsp[12:])
899  return (p,i,d,qpps)
900 
901  ## Command: 57
902  def setMainBatterySettings(self, addr, minV, maxV):
903  sData = ''
904  sData += self.packU16(minV)
905  sData += self.packU16(maxV)
906  self.execCmdWithAckRsp(addr, CmdSetMainBattCutoffs, sData, True)
907 
908  ## Command: 58
909  def setLogicBatterySettings(self, addr, minV, maxV):
910  sData = ''
911  sData += self.packU16(minV)
912  sData += self.packU16(maxV)
913  self.execCmdWithAckRsp(addr, CmdSetLogicCutoffs, sData, True)
914 
915  ## Command: 59
916  def readMainBatterySettings(self, addr):
917  sRsp = self.execCmdWithDataRsp(addr, CmdReadMainBattCutoffs, '', 6)
918  minV = self.unpackU16(sRsp)
919  maxV = self.unpackU16(sRsp[2:])
920  return (minV,maxV)
921 
922  ## Command: 60
923  def readLogicBatterySettings(self, addr):
924  sRsp = self.execCmdWithDataRsp(addr, CmdReadLocicCutoffs, '', 6)
925  minV = self.unpackU16(sRsp)
926  maxV = self.unpackU16(sRsp[2:])
927  return (minV,maxV)
928 
929  ## Command: 61
930  def setM1PositionConstants(self, addr, kp, ki, kd, kimax,
931  deadzone, minP, maxP):
932  sData = ''
933  self.writeU32(kd)
934  self.writeU32(kp)
935  self.writeU32(ki)
936  self.writeU32(kimax)
937  self.writeU32(deadzone)
938  self.writeU32(minP)
939  self.writeU32(maxP)
940  self.execCmdWithAckRsp(addr, CmdSetPosPidMot1, sData, True)
941 
942  ## Command: 62
943  def setM2PositionConstants(self, addr, kp, ki, kd, kimax,
944  deadzone, minP, maxP):
945  sData = ''
946  self.writeU32(kd)
947  self.writeU32(kp)
948  self.writeU32(ki)
949  self.writeU32(kimax)
950  self.writeU32(deadzone)
951  self.writeU32(minP)
952  self.writeU32(maxP)
953  self.execCmdWithAckRsp(addr, CmdSetPosPidMot2, sData, True)
954 
955  ## Command: 63
956  def readM1PositionConstants(self, addr):
957  sRsp = self.execCmdWithDataRsp(addr, CmdReadPosPidMot1, '', 30)
958  p = self.unpackU32(sRsp)
959  i = self.unpackU32(sRsp[4:])
960  d = self.unpackU32(sRsp[8:])
961  imax = self.unpackU32(sRsp[12:])
962  deadzone = self.unpackU32(sRsp[16:])
963  minP = self.unpackU32(sRsp[20:])
964  maxP = self.unpackU32(sRsp[24:])
965  return (p,i,d,imax,deadzone,minP,maxP)
966 
967  ## Command: 64
968  def readM2PositionConstants(self, addr):
969  sRsp = self.execCmdWithDataRsp(addr, CmdReadPosPidMot2, '', 30)
970  p = self.unpackU32(sRsp)
971  i = self.unpackU32(sRsp[4:])
972  d = self.unpackU32(sRsp[8:])
973  imax = self.unpackU32(sRsp[12:])
974  deadzone = self.unpackU32(sRsp[16:])
975  minP = self.unpackU32(sRsp[20:])
976  maxP = self.unpackU32(sRsp[24:])
977  return (p,i,d,imax,deadzone,minP,maxP)
978 
979  ## Command: 65
980  def setM1SpeedAccelDeccelPosition(self, addr, accel, speed, deccel, position,
981  buffered):
982  sData = ''
983  sData += self.packU32(accel)
984  sData += self.packU32(speed)
985  sData += self.packU32(deccel)
986  sData += self.packU32(position)
987  sData += self.packU8(buffered)
988  self.execCmdWithAckRsp(addr, CmdBufDriveQProfPosMot1, sData, True)
989 
990  ## Command: 66
991  def setM2SpeedAccelDeccelPosition(self, addr, accel, speed, deccel, position,
992  buffered):
993  sData = ''
994  sData += self.packU32(accel)
995  sData += self.packU32(speed)
996  sData += self.packU32(deccel)
997  sData += self.packU32(position)
998  sData += self.packU8(buffered)
999  self.execCmdWithAckRsp(addr, CmdBufDriveQProfPosMot2, sData, True)
1000 
1001  ## Command: 67
1002  def setMixedSpeedAccelDeccelPosition(self, addr,
1003  accel1, speed1, deccel1, position1,
1004  accel2, speed2, deccel2, position2,
1005  buffered):
1006  sData = ''
1007  sData += self.packU32(accel1)
1008  sData += self.packU32(speed1)
1009  sData += self.packU32(deccel1)
1010  sData += self.packU32(position1)
1011  sData += self.packU32(accel2)
1012  sData += self.packU32(speed2)
1013  sData += self.packU32(deccel2)
1014  sData += self.packU32(position2)
1015  sData += self.packU8(buffered)
1016  self.execCmdWithAckRsp(addr, CmdBufDriveQProfPos, sData, True)
1017 
1018  ## Command: 82
1019  def readTemperature(self, addr):
1020  sRsp = self.execCmdWithDataRsp(addr, CmdReadTemp, '', 4)
1021  return self.unpackU16(sRsp)
1022 
1023  ## Command: 90
1024  def readStatus(self, addr):
1025  sRsp = self.execCmdWithDataRsp(addr, CmdReadStatus, '', 4)
1026  return self.unpackU16(sRsp)
1027 
1028  ## Command: 91
1029  def readEncoderMode(self, addr):
1030  sRsp = self.execCmdWithDataRsp(addr, CmdReadEncoderMode, '', 4)
1031  mode1 = self.unpackU8(sRsp)
1032  mode2 = self.unpackU8(sRsp[1:])
1033  return (mode1, mode2)
1034 
1035  ## Command: 92
1036  def setM1EncoderMode(self, addr, mode):
1037  self.execCmdWithAckRsp(addr, CmdSetEncoderModeMot1, self.packU8(mode), True)
1038 
1039  ## Command: 93
1040  def setM2EncoderMode(self, addr, mode):
1041  self.execCmdWithAckRsp(addr, CmdSetEncoderModeMot2, self.packU8(mode), True)
1042 
1043  ## Command: 94
1044  def writeSettings(self, addr):
1045  self.execCmdWithAckRsp(addr, CmdWriteEEPROM, '')
1046 
1047  ## Command: 133
1048  ## Note: RoboClass User Manual v5 error. Values are 32 bits.
1049  def setM1MaxCurrentLimit(self, addr, maxAmps):
1050  maxAmps = int(maxAmps)
1051  sData = ''
1052  sData += self.packU32(maxAmps)
1053  sData += self.packU32(0)
1054  self.execCmdWithAckRsp(addr, CmdSetMaxCurrentMot1, sData, True)
1055 
1056  ## Command: 134
1057  ## Note: RoboClass User Manual v5 error. Values are 32 bits.
1058  def setM2MaxCurrentLimit(self, addr, maxAmps):
1059  maxAmps = int(maxAmps)
1060  sData = ''
1061  sData += self.packU32(maxAmps)
1062  sData += self.packU32(0)
1063  self.execCmdWithAckRsp(addr, CmdSetMaxCurrentMot2, sData, True)
1064 
1065  ## Command: 135
1066  ## Note: RoboClass User Manual v5 error. Values are 32 bits.
1067  def readM1MaxCurrentLimit(self, addr):
1068  sRsp = self.execCmdWithDataRsp(addr, CmdReadMaxCurrentMot1, '', 10)
1069  return self.unpackU32(sRsp)
1070 
1071  ## Command: 136
1072  ## Note: RoboClass User Manual v5 error. Values are 32 bits.
1073  def readM2MaxCurrentLimit(self, addr):
1074  sRsp = self.execCmdWithDataRsp(addr, CmdReadMaxCurrentMot2, '', 10)
1075  return self.unpackU32(sRsp)
1076 
1077 
1078 # ------------------------------------------------------------------------------
1079 # UT main
1080 # ------------------------------------------------------------------------------
1081 if __name__ == '__main__':
1082  print "Roboclaw Unit Test Example"
1083  print
1084 
1085  addr = AddrDft
1086 
1087  # Create motor controller object.
1088  motorctlr = RoboClaw()
1089 
1090  # Open communiction
1091  try:
1092  motorctlr.open("/dev/ttyACM0", 1000000)
1093  except RoboClawException as inst:
1094  print >>sys.stderr, "Error:", inst.message
1095  sys.exit(4)
1096 
1097  # Get version string
1098  rcv = motorctlr.readVersion(addr)
1099  print rcv[:-3]
1100 
1101  #
1102  # Print settings
1103  #
1104  minV, maxV = motorctlr.readLogicBatterySettings(addr)
1105  print "Logic Battery: [%.1f, %.1f]" % (minV/10.0, maxV/10.0)
1106 
1107  minV, maxV = motorctlr.readMainBatterySettings(addr)
1108  print "Main Battery: [%.1f, %.1f]" % (minV/10.0, maxV/10.0)
1109 
1110  mode1, mode2 = motorctlr.readEncoderMode(addr)
1111  print "Encoder Modes: 0x%02x, 0x%02x" % (mode1, mode2)
1112 
1113  motorctlr.setM1Pidq(addr, 0x00010000, 0x00008000, 0x00004000, 44000)
1114  motorctlr.setM2Pidq(addr, 0x00010000, 0x00008000, 0x00004000, 44000)
1115 
1116  p,i,d,qpps = motorctlr.readM1Pidq(addr)
1117  print "M1 Velocity PID:"
1118  print " P = 0x%08x" % (p / 65536.0)
1119  print " I = 0x%08x" % (i / 65536.0)
1120  print " D = 0x%08x" % (d / 65536.0)
1121  print " QPPS = %u" % (qpps)
1122 
1123  p,i,d,qpps = motorctlr.readM2Pidq(addr)
1124  print "M2 Velocity PID:"
1125  print " P = 0x%08x" % (p / 65536.0)
1126  print " I = 0x%08x" % (i / 65536.0)
1127  print " D = 0x%08x" % (d / 65536.0)
1128  print " QPPS = %u" % (qpps)
1129 
1130  print
1131 
1132  print "All stop"
1133  motorctlr.setM1Speed(addr, 0)
1134  motorctlr.setM2Speed(addr, 0)
1135 
1136  print "Reset encoders"
1137  motorctlr.resetEncoderCnts(addr)
1138 
1139  print
1140 
1141  cnt = 0
1142  maxcnt = 15
1143  tgtspeed1 = 0
1144  tgtspeed2 = 0
1145 
1146  while True:
1147  cnt=cnt+1
1148  print "Count = ",cnt
1149 
1150  print " Status: 0x%04x" % (motorctlr.readStatus(addr))
1151  print " Temperature: %.1f" % (motorctlr.readTemperature(addr)/10.0)
1152  print " Main Battery: %.1f" % (motorctlr.readMainBattery(addr)/10.0)
1153  print " Logic Battery: %.1f" % (motorctlr.readLogicBattery(addr)/10.0)
1154 
1155  m1cur, m2cur = motorctlr.readCurrents(addr)
1156  print " Current M1: %.1f" % (m1cur/100.0)
1157  print " Current M2: %.1f" % (m2cur/100.0)
1158 
1159  pos1, status1 = motorctlr.readM1Encoder(addr)
1160  pos2, status2 = motorctlr.readM2Encoder(addr)
1161  print " Position M1: %u, 0x%02x" % (pos1, status1)
1162  print " Position M2: %u, 0x%02x" % (pos2, status2)
1163 
1164  tgtspeed1 += 1000
1165  tgtspeed2 += 1000
1166 
1167  if tgtspeed1 > 20000 or tgtspeed2 > 20000:
1168  tgtspeed1 = 0
1169  tgtspeed2 = 0
1170 
1171  print " Set Speeds: %u, %u" % (tgtspeed1, tgtspeed2)
1172  motorctlr.setM1Speed(addr, tgtspeed1)
1173  motorctlr.setM2Speed(addr, tgtspeed2)
1174 
1175  speed1, status1 = motorctlr.readM1Speed(addr)
1176  speed2, status2 = motorctlr.readM2Speed(addr)
1177  print " Speed M1: %u, 0x%02x" % (speed1, status1)
1178  print " Speed M2: %u, 0x%02x" % (speed2, status2)
1179 
1180  time.sleep(2)
1181 
1182  if cnt > maxcnt:
1183  break
1184 
1185  print "Stop"
1186  motorctlr.setM1Speed(addr, 0)
1187  motorctlr.setM2Speed(addr, 0)
def RightMixed(self, addr, val)
Command: 10.
Definition: RoboClaw.py:592
def readVersion(self, addr)
Command: 21.
Definition: RoboClaw.py:640
def setM2SpeedAccelDistance(self, addr, accel, speed, distance, buffered)
Command: 45.
Definition: RoboClaw.py:797
def LeftMixed(self, addr, val)
Command: 11.
Definition: RoboClaw.py:596
def setM2SpeedDistance(self, addr, speed, distance, buffered)
Command: 42.
Definition: RoboClaw.py:769
def setM2EncoderMode(self, addr, mode)
Command: 93.
Definition: RoboClaw.py:1040
def setM2Pidq(self, addr, p, i, d, qpps)
Command: 29.
Definition: RoboClaw.py:686
def setMixedSpeedIAccelDistance(self, addr, accel1, speed1, distance1, accel2, speed2, distance2, buffered)
Command: 51.
Definition: RoboClaw.py:849
def setM2SpeedAccel(self, addr, accel, speed)
Command: 39.
Definition: RoboClaw.py:746
def setMixedSpeedDistance(self, addr, speed1, distance1, speed2, distance2, buffered)
Command: 43.
Definition: RoboClaw.py:778
def packS16(self, val)
Definition: RoboClaw.py:360
def M1Forward(self, addr, val)
Command: 0.
Definition: RoboClaw.py:552
def open(self, device, baudrate, fnChipSelect=None)
Open connection to motor controller(s).
Definition: RoboClaw.py:259
RobotClaw Motor Controller class.
Definition: RoboClaw.py:240
def setM2MaxCurrentLimit(self, addr, maxAmps)
Command: 134 Note: RoboClass User Manual v5 error.
Definition: RoboClaw.py:1058
message
error message attribute
Definition: RoboClaw.py:224
def execCmdWithDataRsp(self, addr, cmdId, sCmdData, lenRsp, appendCrc=False)
Execute command with data response.
Definition: RoboClaw.py:324
def setM2PositionConstants(self, addr, kp, ki, kd, kimax, deadzone, minP, maxP)
Command: 62.
Definition: RoboClaw.py:944
def readM1PositionConstants(self, addr)
Command: 63.
Definition: RoboClaw.py:956
m_fnChipSelect
last address
Definition: RoboClaw.py:249
def setM1PositionConstants(self, addr, kp, ki, kd, kimax, deadzone, minP, maxP)
Command: 61.
Definition: RoboClaw.py:931
def readLogicBattery(self, addr)
Command: 25.
Definition: RoboClaw.py:672
def setM1DutyAccel(self, addr, accel, duty)
Command: 52.
Definition: RoboClaw.py:861
def readTemperature(self, addr)
Command: 82.
Definition: RoboClaw.py:1019
def readM2Encoder(self, addr)
Command: 17.
Definition: RoboClaw.py:615
def readCurrents(self, addr)
Command: 49 Note: RoboClaw User Manual v5 error.
Definition: RoboClaw.py:827
def M2Forward(self, addr, val)
Command: 4.
Definition: RoboClaw.py:568
def readM1Speed(self, addr)
Command: 18.
Definition: RoboClaw.py:622
def setM2Speed(self, addr, val)
Command: 36.
Definition: RoboClaw.py:728
def readEncoderMode(self, addr)
Command: 91.
Definition: RoboClaw.py:1029
def readBufferCnts(self, addr)
Command: 47.
Definition: RoboClaw.py:819
def packS32(self, val)
Definition: RoboClaw.py:366
def setMixedDuty(self, addr, m1, m2)
Command: 34.
Definition: RoboClaw.py:717
def __init__(self)
Constructor.
Definition: RoboClaw.py:245
def DriveM1(self, addr, val)
Command: 6.
Definition: RoboClaw.py:576
def writeU32(self, val)
Definition: RoboClaw.py:522
def setMixedSpeed(self, addr, m1, m2)
Command: 37.
Definition: RoboClaw.py:732
def readM2instspeed(self, addr)
Command: 31.
Definition: RoboClaw.py:702
def noop(self, port, addrSel, addrLast)
Definition: RoboClaw.py:281
def readM1MaxCurrentLimit(self, addr)
Command: 135 Note: RoboClass User Manual v5 error.
Definition: RoboClaw.py:1067
def setM1Speed(self, addr, val)
Command: 35.
Definition: RoboClaw.py:724
def setM1SpeedDistance(self, addr, speed, distance, buffered)
Command: 41.
Definition: RoboClaw.py:761
def packU16(self, val)
Definition: RoboClaw.py:357
def setM2DutyAccel(self, addr, accel, duty)
Command: 53.
Definition: RoboClaw.py:868
def execCmdWithAckRsp(self, addr, cmdId, sCmdData, appendCrc=False)
Execute command with acknowledgement response.
Definition: RoboClaw.py:296
def DriveM2(self, addr, val)
Command: 7.
Definition: RoboClaw.py:580
def setMixedDutyAccel(self, addr, accel1, duty1, accel2, duty2)
Command: 54.
Definition: RoboClaw.py:875
def readM2MaxCurrentLimit(self, addr)
Command: 136 Note: RoboClass User Manual v5 error.
Definition: RoboClaw.py:1073
def readM1Encoder(self, addr)
Command: 16.
Definition: RoboClaw.py:608
def readStatus(self, addr)
Command: 90.
Definition: RoboClaw.py:1024
def resetEncoderCnts(self, addr)
Command: 20.
Definition: RoboClaw.py:636
def TurnMixed(self, addr, val)
Command: 13.
Definition: RoboClaw.py:604
def setMixedSpeedAccelDistance(self, addr, accel, speed1, distance1, speed2, distance2, buffered)
Command: 46.
Definition: RoboClaw.py:808
def setM1SpeedAccel(self, addr, accel, speed)
Command: 38.
Definition: RoboClaw.py:739
def crc16(self, crc, buf)
Definition: RoboClaw.py:387
def setM1MaxCurrentLimit(self, addr, maxAmps)
Command: 133 Note: RoboClass User Manual v5 error.
Definition: RoboClaw.py:1049
def readM2Speed(self, addr)
Command: 19.
Definition: RoboClaw.py:629
def unpackU32(self, s)
Definition: RoboClaw.py:381
def ForwardMixed(self, addr, val)
Command: 8.
Definition: RoboClaw.py:584
def readMainBatterySettings(self, addr)
Command: 59.
Definition: RoboClaw.py:916
def packU32(self, val)
Definition: RoboClaw.py:363
def readLogicBatterySettings(self, addr)
Command: 60.
Definition: RoboClaw.py:923
def M2Backward(self, addr, val)
Command: 5.
Definition: RoboClaw.py:572
def setM1SpeedAccelDeccelPosition(self, addr, accel, speed, deccel, position, buffered)
Command: 65.
Definition: RoboClaw.py:981
def readM2PositionConstants(self, addr)
Command: 64.
Definition: RoboClaw.py:968
def setM2SpeedAccelDeccelPosition(self, addr, accel, speed, deccel, position, buffered)
Command: 66.
Definition: RoboClaw.py:992
def writeSettings(self, addr)
Command: 94.
Definition: RoboClaw.py:1044
def setMixedSpeedIAccel(self, addr, accel1, speed1, accel2, speed2)
Command: 50.
Definition: RoboClaw.py:838
def setMaxMainBattery(self, addr, val)
Command: 3.
Definition: RoboClaw.py:564
def unpackU16(self, s)
Definition: RoboClaw.py:375
def setM1Pidq(self, addr, p, i, d, qpps)
Command: 28.
Definition: RoboClaw.py:677
def DriveMixed(self, addr, val)
Command: 12.
Definition: RoboClaw.py:600
def setM1SpeedAccelDistance(self, addr, accel, speed, distance, buffered)
Command: 44.
Definition: RoboClaw.py:788
def BackwardMixed(self, addr, val)
Command: 9.
Definition: RoboClaw.py:588
def readM2Pidq(self, addr)
Command: 56.
Definition: RoboClaw.py:893
m_port
checksum (deprecated)
Definition: RoboClaw.py:247
def readM1instspeed(self, addr)
Command: 30.
Definition: RoboClaw.py:695
def __init__(self, msg)
Constructor.
Definition: RoboClaw.py:222
def readMainBattery(self, addr)
Command: 24.
Definition: RoboClaw.py:667
def packU8(self, val)
Definition: RoboClaw.py:351
def setMixedSpeedAccel(self, addr, accel, speed1, speed2)
Command: 40.
Definition: RoboClaw.py:753
def setM1EncoderMode(self, addr, mode)
Command: 92.
Definition: RoboClaw.py:1036
def setMinMainBattery(self, addr, val)
Command: 2.
Definition: RoboClaw.py:560
RoboClaw exception class.
Definition: RoboClaw.py:216
def M1Backward(self, addr, val)
Command: 1.
Definition: RoboClaw.py:556
def unpackU8(self, s)
Definition: RoboClaw.py:369
m_addrLast
serial port
Definition: RoboClaw.py:248
def setLogicBatterySettings(self, addr, minV, maxV)
Command: 58.
Definition: RoboClaw.py:909
def setM2Duty(self, addr, val)
Command: 33.
Definition: RoboClaw.py:713
def readM1Pidq(self, addr)
Command: 55.
Definition: RoboClaw.py:884
m_isOpen
board chip select
Definition: RoboClaw.py:250
def setMixedSpeedAccelDeccelPosition(self, addr, accel1, speed1, deccel1, position1, accel2, speed2, deccel2, position2, buffered)
Command: 67.
Definition: RoboClaw.py:1005
def setMainBatterySettings(self, addr, minV, maxV)
Command: 57.
Definition: RoboClaw.py:902
def setM1Duty(self, addr, val)
Command: 32.
Definition: RoboClaw.py:709