libkovan  1
The kovan standard library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
create.hpp
Go to the documentation of this file.
1 /**************************************************************************
2  * Copyright 2012 KISS Institute for Practical Robotics *
3  * *
4  * This file is part of libkovan. *
5  * *
6  * libkovan is free software: you can redistribute it and/or modify *
7  * it under the terms of the GNU General Public License as published by *
8  * the Free Software Foundation, either version 2 of the License, or *
9  * (at your option) any later version. *
10  * *
11  * libkovan is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14  * GNU General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU General Public License *
17  * along with libkovan. Check the LICENSE file in the project root. *
18  * If not, see <http://www.gnu.org/licenses/>. *
19  **************************************************************************/
20 
34 #ifndef _CREATE_HPP_
35 #define _CREATE_HPP_
36 
37 #include <cstdio>
38 #include <cstdlib>
39 #include <vector>
40 #include <sys/time.h>
41 
42 #ifndef WIN32
43 #include <termios.h>
44 #include <pthread.h>
45 #else
46 typedef unsigned int speed_t;
47 #endif
48 
49 #include "sensor.hpp"
50 #include "button.hpp"
51 #include "export.h"
52 
53 #define PI 3.14159f
54 
60 {
61 public:
62  CreateScript();
63  CreateScript(const CreateScript& rhs);
64 
65  void append(const unsigned char& byte);
66  void append(const unsigned char *data, const size_t& size);
67  void append(const CreateScript& script);
68 
69  void remove(const size_t& i, const size_t& len = 1);
70 
71  const unsigned char *data() const;
72  size_t size() const;
73 
74  unsigned char byte(const size_t& i);
75 
76  CreateScript& operator=(const CreateScript& rhs);
77 
78 private:
79  std::vector<unsigned char> m_script;
80 };
81 
86 {
87  timeval timestamp;
88 
89  int distance;
90  int angle;
91  short radius;
93  short leftVelocity;
94 };
95 
99 namespace CreatePackets
100 {
104  struct _1
105  {
106  unsigned char bumpsAndWheelDrops;
107  unsigned char wall;
108  unsigned char cliffLeft;
109  unsigned char cliffFrontLeft;
110  unsigned char cliffFrontRight;
111  unsigned char cliffRight;
112  unsigned char virtualWall;
113  unsigned char cargoBayDigitalInputs;
115  };
116 
120  struct _2
121  {
122  unsigned char ir;
123  unsigned char buttons;
124  unsigned char distance[2];
125  unsigned char angle[2];
126  };
127 
131  struct _3
132  {
133  unsigned char chargingState;
134  unsigned char voltage[2];
135  char current[2];
137  unsigned char batteryCharge[2];
138  unsigned char batteryCapacity[2];
139  };
140 
144  struct _4
145  {
146  unsigned char wallSignal[2];
147  unsigned char cliffLeftSignal[2];
148  unsigned char cliffFrontLeftSignal[2];
149  unsigned char cliffFrontRightSignal[2];
150  unsigned char cliffRightSignal[2];
151  unsigned char userDigitalInputs;
152  unsigned char userAnalogInput[2];
154  };
155 
159  struct _5
160  {
161  unsigned char mode;
162  unsigned char songNumber;
163  unsigned char songPlaying;
164  unsigned char numberOfStreamPackets;
165  char velocity[2];
166  char radius[2];
167  char rightVelocity[2];
168  char leftVelocity[2];
169  };
170 }
171 
172 namespace CreateSensors
173 {
174  class PlayButton;
175  class AdvanceButton;
176  class Wall;
177  class CliffLeft;
178  class CliffFrontLeft;
179  class CliffFrontRight;
180  class CliffRight;
181  class VirtualWall;
182  class WallSignal;
183  class CliffLeftSignal;
184  class CliffFrontLeftSignal;
185  class CliffFrontRightSignal;
186  class CliffRightSignal;
187  class CargoBayAnalogSignal;
188  class CargoBayDigitalInputs;
189  class IR;
190  class ChargingState;
191  class BatteryTemperature;
192  class BatteryCharge;
193  class BatteryCapacity;
194  class Angle;
195  class Distance;
196  class BumpLeft;
197  class BumpRight;
198  class WheelDropRight;
199  class WheelDropLeft;
200  class WheelDropCaster;
201 }
202 
211 {
212 public:
219  enum Mode {
223  FullMode
224  };
225 
226  ~Create();
227 
234  bool connect();
235 
242  bool disconnect();
243 
249  bool isConnected() const;
250 
251  void setPassiveMode();
252  void setSafeMode();
253  void setFullMode();
254 
255  void setMode(const Create::Mode& mode);
256  Create::Mode mode();
257 
258  void send(const CreateScript& script);
259 
260  bool write(const unsigned char& c);
261  bool write(const unsigned char *data, const size_t& len);
262 
263  void flush();
264 
269  short read();
270 
277  int read(unsigned char *data, const size_t& len);
278 
286  bool blockingRead(unsigned char *data, const size_t& size, unsigned timeout = 25);
287 
288 
289  template<typename T>
290  inline bool blockingRead(T& data, unsigned timeout = 0)
291  {
292  return blockingRead(reinterpret_cast<unsigned char *>(&data), sizeof(T),
293  timeout ? timeout : sizeof(T) * 7);
294  }
295 
296  void setLeds(const bool& advance, const bool& play, const unsigned char& color, const unsigned char& brightness);
297 
298  void drive(const short& velocity, const short& radius);
299  void driveDirect(const short& left, const short& right);
300  inline void driveStraight(const short& speed) { driveDirect(speed, speed); }
301  inline void stop()
302  {
303  flush();
304  driveStraight(0);
305  }
306 
313  void turn(const short& angle, const unsigned short& speed);
314 
321  void move(const short& millimeters, const unsigned short& speed);
322 
327  void spin(const short& speed);
328 
334  short angularVelocity() const;
335 
336  inline void spinClockwise(const short& speed) { spin(-speed); }
337  inline void spinCounterClockwise(const short& speed) { spin(speed); }
338 
339  bool setBaudRate(const unsigned char& baudCode);
340 
341  void setDistance(const int distance);
342  void setAngle(const int angle);
343 
344  // High level sensors
345  AbstractButton *playButton() const;
346  AbstractButton *advanceButton() const;
347 
348  Sensor<bool> *wall() const;
349  Sensor<bool> *cliffLeft() const;
350  Sensor<bool> *cliffFrontLeft() const;
351  Sensor<bool> *cliffFrontRight() const;
352  Sensor<bool> *cliffRight() const;
353  Sensor<bool> *virtualWall() const;
354 
355  Sensor<unsigned short> *wallSignal() const;
356  Sensor<unsigned short> *cliffLeftSignal() const;
357  Sensor<unsigned short> *cliffFrontLeftSignal() const;
358  Sensor<unsigned short> *cliffFrontRightSignal() const;
359  Sensor<unsigned short> *cliffRightSignal() const;
360  Sensor<unsigned short> *cargoBayAnalogSignal() const;
361  Sensor<unsigned char> *cargoBayDigitalInputs() const;
362 
363  Sensor<unsigned char> *ir() const;
364 
365  Sensor<unsigned char> *chargingState() const;
366  Sensor<char> *batteryTemperature() const;
367  Sensor<unsigned short> *batteryCharge() const;
368  Sensor<unsigned short> *batteryCapacity() const;
369 
370  Sensor<int> *angle() const;
371  Sensor<int> *distance() const;
372 
373  Sensor<bool> *bumpLeft() const;
374  Sensor<bool> *bumpRight() const;
375 
376  Sensor<bool> *wheelDropLeft() const;
377  Sensor<bool> *wheelDropRight() const;
378  Sensor<bool> *wheelDropCaster() const;
379 
380  void setRefreshRate(const unsigned short& refreshRate);
381  const unsigned short& refreshRate() const;
382 
388  static Create *instance();
389 
390  const CreateState *state();
391  const CreatePackets::_1 *sensorPacket1();
392  const CreatePackets::_2 *sensorPacket2();
393  const CreatePackets::_3 *sensorPacket3();
394  const CreatePackets::_4 *sensorPacket4();
395  const CreatePackets::_5 *sensorPacket5();
396 
397  inline void beginAtomicOperation()
398  {
399  #ifndef WIN32
400  pthread_mutex_lock(&m_mutex);
401  #endif
402  }
403 
404  inline void endAtomicOperation()
405  {
406  #ifndef WIN32
407  pthread_mutex_unlock(&m_mutex);
408  #endif
409  }
410 
411 private:
412  Create();
413  Create(const Create& rhs);
414  Create& operator=(const Create& rhs);
415 
416  void setLocalBaudRate(const speed_t& baudRate);
417 
418  bool start();
419 
420  bool open();
421  void close();
422 
423  template<typename T>
424  inline void lazyDelete(T *&ptr)
425  {
426  if(ptr) delete ptr;
427  }
428 
429  inline timeval timeOfDay() const
430  {
431  timeval ret;
432  gettimeofday(&ret, NULL);
433  return ret;
434  }
435 
436  inline bool hasRequiredTimePassed(const timeval& timestamp) const
437  {
438  #ifndef WIN32
439  timeval current = timeOfDay();
440  timeval result;
441  timersub(&current, &timestamp, &result);
442  const long msecs = result.tv_sec * 1000 + result.tv_usec / 1000;
443  return msecs > m_refreshRate;
444  #else
445  #warning Create library not yet implemented for Windows
446  #endif
447  }
448 
449  inline double timevalToFloat(const timeval& tv)
450  {
451  return ((double)tv.tv_sec) + ((double)tv.tv_usec / 1000000.0);
452  }
453 
454  inline float deg2rad(const float& deg)
455  {
456  return deg / 180.0 * PI;
457  }
458 
459  void updateState();
460 
461  void updateSensorPacket1();
462  void updateSensorPacket2(bool forceUpdate = false);
463  void updateSensorPacket3();
464  void updateSensorPacket4();
465  void updateSensorPacket5();
466 
467  CreateState m_state;
468 
469  unsigned short m_refreshRate;
470 
471  CreatePackets::_1 m_1;
472  CreatePackets::_2 m_2;
473  CreatePackets::_3 m_3;
474  CreatePackets::_4 m_4;
475  CreatePackets::_5 m_5;
476  timeval timestamps[5];
477 
478 
479  // These are all marked mutable because they
480  // are initialized lazily in a const accessor.
481  // I have yet to decide if this is the "correct"
482  // way to go about it.
483  mutable CreateSensors::PlayButton *m_playButton;
484  mutable CreateSensors::AdvanceButton *m_advanceButton;
485 
486  mutable CreateSensors::Wall *m_wall;
487  mutable CreateSensors::CliffLeft *m_cliffLeft;
488  mutable CreateSensors::CliffFrontLeft *m_cliffFrontLeft;
489  mutable CreateSensors::CliffFrontRight *m_cliffFrontRight;
490  mutable CreateSensors::CliffRight *m_cliffRight;
491  mutable CreateSensors::VirtualWall *m_virtualWall;
492 
493  mutable CreateSensors::WallSignal *m_wallSignal;
494  mutable CreateSensors::CliffLeftSignal *m_cliffLeftSignal;
495  mutable CreateSensors::CliffFrontLeftSignal *m_cliffFrontLeftSignal;
496  mutable CreateSensors::CliffFrontRightSignal *m_cliffFrontRightSignal;
497  mutable CreateSensors::CliffRightSignal *m_cliffRightSignal;
498  mutable CreateSensors::CargoBayAnalogSignal *m_cargoBayAnalogSignal;
499  mutable CreateSensors::CargoBayDigitalInputs *m_cargoBayDigitalInputs;
500 
501  mutable CreateSensors::IR *m_ir;
502 
503  mutable CreateSensors::ChargingState *m_chargingState;
504  mutable CreateSensors::BatteryTemperature *m_batteryTemperature;
505  mutable CreateSensors::BatteryCharge *m_batteryCharge;
506  mutable CreateSensors::BatteryCapacity *m_batteryCapacity;
507 
508  mutable CreateSensors::Angle *m_angle;
509  mutable CreateSensors::Distance *m_distance;
510 
511  mutable CreateSensors::BumpLeft *m_bumpLeft;
512  mutable CreateSensors::BumpRight *m_bumpRight;
513 
514  mutable CreateSensors::WheelDropLeft *m_wheelDropLeft;
515  mutable CreateSensors::WheelDropRight *m_wheelDropRight;
516  mutable CreateSensors::WheelDropCaster *m_wheelDropCaster;
517 
518  size_t m_i;
519  CreateScript m_script;
520  int m_tty;
521 #ifndef WIN32
522  pthread_mutex_t m_mutex;
523 #endif
524 };
525 
526 #endif