nxtdc.hh
1 /*
2  * Player - One Hell of a Robot Server
3  * Copyright (C) 2010
4  * Alejandro R. Mosteo
5  *
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include <libusb.h>
23 #include <stdexcept>
24 #include <vector>
25 
26 namespace NXT
27  {
28 
29  using namespace std;
30 
31  typedef vector<unsigned char> protobuffer;
32 
33  class buffer : public protobuffer
34  {
35  public:
36  buffer & append_byte ( uint8_t byte );
37  buffer & append_word ( uint16_t word );
38  buffer & append ( const buffer & buf );
39  // return self to chain calls
40 
41  void dump ( const string & header ) const; // Debug to stdout
42  };
43 
44  class transport
45  {
46  public:
47  virtual void write ( const buffer &buf ) = 0;
48  virtual buffer read ( void ) = 0;
49  };
50 
51  class USB_transport : public transport
52  {
53  public:
54  USB_transport ( void );
55  ~USB_transport ( void );
56  virtual void write ( const buffer &buf );
57  virtual buffer read ( void );
58  private:
59  libusb_context *context_;
60  libusb_device_handle *handle_;
61 
62  void usb_check ( int usb_error );
63  };
64 
65  class nxt_error : public runtime_error
66  {
67  public :
68  nxt_error ( const char *s ) : runtime_error ( s ) {};
69  nxt_error ( const string & s ) : runtime_error ( s ) {};
70  };
71 
72  enum motors
73  {
74  A = 0x00,
75  B = 0x01,
76  C = 0x02,
77  All = 0xFF
78  };
79 
80  enum motor_modes
81  {
82  motor_on = 0x01,
83  motor_brake = 0x02,
84  motor_regulated = 0x04
85  };
86 
87  enum regulation_modes
88  {
89  regulation_motor_idle = 0x00,
90  regulation_motor_speed = 0x01,
91  regulation_motor_sync = 0x02
92  };
93 
94  enum motor_run_states
95  {
96  motor_run_state_idle = 0x00,
97  motor_run_state_ramp_up = 0x10,
98  motor_run_state_running = 0x20,
99  motor_run_state_rampdown = 0x40
100  };
101 
102  typedef struct
103  {
104  uint8_t protocol_minor;
105  uint8_t protocol_major;
106  uint8_t firmware_minor;
107  uint8_t firmware_major;
108  } versions;
109 
110  typedef struct
111  {
112  char brick_name[15]; // Null-terminated
113  char bluetooth_address[7]; // Null-terminated
114  } device_info;
115 
116  typedef struct
117  {
118  uint8_t motor;
119  int8_t power_pct;
120  motor_modes mode;
121  regulation_modes regulation;
122  int8_t turn_ratio;
123  motor_run_states state;
124  int32_t tacho_limit; // programmed limit for current movement, if any
125  int32_t tacho_count; // current tacho count since last reset (acummulated odometry)
126  int32_t block_tacho_count; // current pos relative to last programmed pos (delta odometry)
127  int32_t rotation_count; // current pos relative to the last reset of rot. counter
128  } output_state;
129  // Beware: the delta is since last command, not since last reading!
130 
131  class brick
132  {
133 
134  public:
135 
136  // Connect to the first brick found
137  // TODO: give some means of connecting to a particular brick.
138  // As is, this library serves only for using with a single brick.
139  brick ( void );
140 
141  ~brick ( void );
142 
143  // Execute a prepared command
144  // When with_feedback, the brick is asked to confirm proper execution
145  // Returns the reply buffer, with the reply flag byte, status, and etc.
146  // or an empty buffer if !with_feedback
147  buffer execute ( const buffer &command, bool with_feedback = false );
148 
149  // PREPARED COMMANDS
150  // That you an store and execute with or without feedback
151 
152  buffer prepare_play_tone ( uint16_t tone_Hz, uint16_t duration_ms );
153 
154  buffer prepare_output_state (
155  motors motor,
156  int8_t power_pct,
157  motor_modes mode = motor_brake,
158  regulation_modes regulation = regulation_motor_speed,
159  int8_t turn_ratio = 0,
160  motor_run_states state = motor_run_state_running,
161  uint32_t tacho_count = 0 );
162  // Full motor control; refer to NXT docs for precise meanings...
163 
164  buffer prepare_reset_motor_position ( motors motor, bool relative_to_last_position = false );
165  buffer prepare_stop_sound_playback ( void );
166  buffer prepare_keep_alive ( void );
167 
168  // DIRECT PERFORMING (WITH FEEDBACK)
169  // If you don't want the feedback overhead, use execute with prepared commands
170  // Errors will be reported as thrown nxt_error
171 
172  void play_tone ( uint16_t tone_Hz, uint16_t duration_ms );
173 
174  // Simple motor control
175  void set_motor ( motors motor, int8_t power_pct );
176 
177  output_state get_motor_state ( motors motor );
178 
179  // In millivolts
180  uint16_t get_battery_level ( void );
181 
182  versions get_version ( void );
183 
184  device_info get_device_info ( void );
185 
186  // Run a 10-second loop of play_tone, to get the average time per commands
187  // For testing purposes, yes.
188  void msg_rate_check ( void );
189 
190  private:
191 
192  enum telegram_types
193  {
194  direct_command_with_response = 0x00,
195  system_command_with_response = 0x01,
196  reply = 0x02,
197  direct_command_without_response = 0x80,
198  system_command_without_response = 0x80
199  };
200 
201  buffer assemble ( telegram_types teltype,
202  uint8_t command,
203  const buffer & payload );
204  // Assembles the full telegram to be sent over usb or bluetooth.
205 
206  USB_transport link_;
207  // For now is a fixed USB transport, but we could easily add bluetooth here
208 
209  };
210 
211 }
Definition: nxtdc.hh:131
Definition: nxtdc.hh:102
Definition: nxtdc.hh:51
Definition: nxtdc.hh:110
Definition: nxtdc.hh:116
Definition: nxtdc.hh:65
Definition: nxtdc.hh:33
Definition: nxtdc.hh:44