Aruna
movement.cpp
Go to the documentation of this file.
1 //
2 // Created by noeel on 27-3-19.
3 //
4 
5 
6 #include <aruna/movement.h>
7 #include <set>
8 #include <aruna/comm.h>
10 #include <pthread.h>
11 #include "aruna/log.h"
12 
13 namespace aruna { namespace movement {
14 
15 namespace {
16 // variables
20  std::set<Actuator *> drivers;
21 
22  axis_t<int16_t> currentSpeed = {0, 0, 0, 0, 0, 0};
23  axis_t<int16_t> currentVelocity = {0, 0, 0, 0, 0, 0};
24  axis_t<int16_t> currentDegree = {0, 0, 0, 0, 0, 0};
26 
27 
28 }
29 
31 // check movement status.
33  return movement_status;
34 
35  log = new log::channel_t("Movement");
36 // check if we got drivers
37  if (drivers.empty()) {
38  log->warning("Start failed: No drivers found!");
39  return movement_status;
40  }
41 
42 // start all drivers
43  for (Actuator *d: drivers) {
44  err_t stat = d->startup_error;
45  if (stat != err_t::OK)
46 // TODO print driver name?
47  log->warning("Driver failed to start: %s", err_to_char.at(stat));
48  }
49 
50 // start threads.
51  pthread_create(&movement_comm_handler, NULL, comm_handler_task, NULL);
53  return movement_status;
54 }
55 
57  return movement_status;
58 }
59 
60 void* comm_handler_task(void *arg) {
61  enum comm_commands_t {
62  NO_COMMAND = 0x00,
63 
64 // basic functionality
65  SET_SPEED = 0x01,
66  GET_SPEED = 0x02,
67  SET_VELOCITY = 0x03,
68  GET_VELOCITY = 0x04,
69  SET_DEGREE = 0x05,
70  GET_DEGREE = 0x06,
71  GET_DIRECTION = 0x07,
72 
73 // closed loop configuration
74  SET_DAMPING = 0x10,
75  GET_DAMPING = 0x11,
76 
77 // debugging
78  SET_RUNNING_STATE = 0x20,
79  GET_RUNNING_STATE = 0x21,
80  TEST_SENSORS = 0x22,
81  CALIBRATE_SENSORS = 0x23,
82  GET_SUPPORTED_AXIS = 0x24,
83  SET_SENSOR_OFFSET = 0x25,
84  GET_SENSOR_OFFSET = 0x26,
85  ACTIVATE_MPU = 0x27,
86  GET_MPU_STATUS = 0x28,
87 
88 // advanched automated control
89  RETURN_HOME = 0x30,
90  SET_HOME = 0x31,
91  GOTO_CORDINATES = 0x32,
92  };
93 // initialize comms
95  uint8_t mask;
96  uint8_t flags;
97  int16_t data;
98  uint8_t buffer[6];
99  axis_mask_t active_axis;
100  comm::channel_t movement_channel = {
101  .port = 3,
102  };
103  int16_t (*get_value)(axis_mask_t mode);
104  void (*set_value)(axis_mask_t mode, int16_t speed);
105  comm_commands_t command;
106  if((int) movement_channel.register_err) {
107  log->error("failed to register comm channel: %s", err_to_char.at(movement_channel.register_err));
108  }
109  while (1) {
110  if (movement_channel.receive(&request)) {
111 // if (request.data_received_lenght < 2)
112 // continue;
113  flags = request.data_received[1];
114  data = ((uint16_t) request.data_received[2] << 8) | request.data_received[3];
115  get_value = nullptr;
116  set_value = nullptr;
117  command = NO_COMMAND;
118  log->debug("comm command:%X, flag:%X, data:%d", request.data_received[0], request.data_received[1], data);
119  switch (request.data_received[0]) {
120 // basic functionality
121 
122  case GET_DEGREE:
123  if ((flags & ((uint8_t) axis_mask_t::X | (uint8_t) axis_mask_t::Y | (uint8_t) axis_mask_t::Z)))
124  break;
125  get_value = get_degree;
126  command = GET_DEGREE;
127  case GET_VELOCITY:
128  if (command == NO_COMMAND) {
129  get_value = get_velocity;
130  command = GET_VELOCITY;
131  }
132  case GET_SPEED:
133  if (command == NO_COMMAND) {
134  command = GET_SPEED;
135  get_value = get_speed;
136  }
137  mask = 1;
138  int16_t speed;
139  active_axis = get_active_axis();
140  for (int i = 0; i < (uint8_t) axis_mask_t::MAX; ++i) {
141  mask = 0b1 << i;
142  if (mask & flags & (uint8_t) active_axis) {
143  buffer[0] = command;
144  buffer[1] = mask;
145  speed = get_value((axis_mask_t) mask);
146  buffer[2] = (speed >> 8);
147  buffer[3] = speed & 0xff;
148 // log->debug("mask: %X flag: %X", mask, flags);
149 // log->debug("GET_COMMAND: %X, value: %d",command, speed);
150 // TODO error check comm.send return value
151  movement_channel.send(request.from_port, buffer, 4);
152  }
153  }
154  break;
155 // set target velocity yaw, roll, pitch, x, y, z
156  case SET_DEGREE:
157  if ((flags & ((uint8_t) axis_mask_t::X | (uint8_t) axis_mask_t::Y | (uint8_t) axis_mask_t::Z)))
158  break;
159  set_value = set_degree;
160  command = SET_DEGREE;
161  case SET_VELOCITY:
162  if (command == NO_COMMAND) {
163  set_value = set_velocity;
164  command = SET_VELOCITY;
165  }
166  case SET_SPEED:
167  if (command == NO_COMMAND) {
168  set_value = set_speed;
169  command = SET_SPEED;
170  }
171  log->verbose("command: %X, axis: 0X%02X, speed: %i", command, flags, data);
172  set_value((axis_mask_t) flags, data);
173  break;
174 // control
175 
176 // get damping
177  case GET_DAMPING:
178  mask = 1;
179  active_axis = get_active_axis();
180  for (int j = 0; j < (uint8_t) axis_mask_t::MAX; ++j) {
181  mask = 1 << j;
182  if (mask & flags & (uint8_t) active_axis) {
183  buffer[0] = GET_DAMPING;
184  buffer[1] = mask;
185  buffer[2] = (uint8_t) get_damping((axis_mask_t) mask);
186  movement_channel.send(request.from_port, buffer, 3);
187  }
188  }
189  break;
190 // set damping
191  case SET_DAMPING:
192  set_damping((axis_mask_t) flags, (damping_t) data);
193  break;
194 
195 // debugging
196 
197 // get running state
198  case GET_RUNNING_STATE:
199  buffer[0] = GET_RUNNING_STATE;
200  buffer[1] = (uint8_t) get_status();
201  movement_channel.send(request.from_port, buffer, 2);
202  break;
203 // set running state
204  case SET_RUNNING_STATE:
205 // TODO return success?
206  switch (data) {
207  case (uint8_t) status_t::RUNNING :
208  start();
209  break;
210  case (uint8_t) status_t::STOPPED:
211  stop();
212  break;
213  default:
214  break;
215  }
216  break;
217 // test sensors
218  case TEST_SENSORS:
219  uint8_t t;
220  t = test_sensor();
221  buffer[0] = TEST_SENSORS;
222  buffer[1] = t;
223  movement_channel.send(request.from_port, buffer, 2);
224  break;
225 // calibrate sensors
226  case CALIBRATE_SENSORS:
228  break;
229 // get supported modes
230  case GET_SUPPORTED_AXIS:
231  buffer[0] = GET_SUPPORTED_AXIS;
232  buffer[1] = (uint8_t) get_active_axis();
233  movement_channel.send(request.from_port, buffer, 2);
234  break;
235  case SET_SENSOR_OFFSET:
236  case GET_SENSOR_OFFSET:
237  break;
238  case ACTIVATE_MPU:
239 // TODO disable support also?
240  break;
241  case GET_MPU_STATUS:
242  buffer[0] = GET_MPU_STATUS;
243  movement_channel.send(request.from_port, buffer, 1);
244  break;
245 // advanced automated control
246 
247 // return home
248  case RETURN_HOME:
249 // set home
250  case SET_HOME:
251 // goto cordinates
252  case GOTO_CORDINATES:
253 // protocol error
254  default:
255  break;
256  }
257  movement_channel.receive_clear();
258  }
259  }
260  pthread_exit(0);
261 }
262 
265  return movement_status;
266 
267  // stop all drivers
268  for (Actuator *d: drivers) {
269  delete d;
270  }
271 
272 // stop task
273  pthread_cancel(movement_comm_handler);
275  return movement_status;
276 }
277 
279  if (drivers.find(driver) != drivers.end()) {
280  return err_t::DRIVER_EXISTS;
281  }
282  if (!drivers.insert(driver).second)
283  return err_t::BUFFER_OVERFLOW;
284  return err_t::OK;
285 }
286 
288 // TODO
289 }
290 
291 uint8_t test_sensor() {
292 // TODO
293  return 1;
294 }
295 
296 void set_speed(axis_mask_t axisMask, int16_t speed) {
297  uint8_t j = 1;
298  err_t ret;
299  axis_mask_t active_axis = get_active_axis();
300  for (Actuator *d: drivers) {
301  ret = d->set(axisMask, speed);
302  if (ret != err_t::OK) {
303  log->warning("setting speed of driver failed: %s", err_to_char.at(ret));
304  }
305  }
306  for (int i = 0; i < (uint8_t) axis_mask_t::MAX; i++) {
307  j= 1 << i;
308  if ((uint8_t) axisMask & j & (uint8_t) active_axis) {
309  currentSpeed[j] = speed;
310  }
311  }
312 }
313 
314 int16_t get_speed(axis_mask_t single_axis) {
315  return currentSpeed[(uint8_t) single_axis];
316 }
317 
318 int16_t get_velocity(axis_mask_t single_axis) {
319  return currentVelocity[(uint8_t) single_axis];
320 }
321 
322 int16_t get_degree(axis_mask_t single_axis) {
323  if ((uint8_t) single_axis & ((uint8_t) axis_mask_t::X | (uint8_t) axis_mask_t::Y | (uint8_t) axis_mask_t::Z))
324  return 0;
325  return currentDegree[(uint8_t) single_axis];
326 }
327 
328 
329 void set_degree(axis_mask_t axisMask, int16_t degree) {
330 // TODO
331 }
332 
333 void set_velocity(axis_mask_t axisMask, int16_t mm_per_second) {
334 // TODO
335 }
336 
338  uint8_t modes = 0;
339  for (Actuator *d: drivers) {
340  modes |= (uint8_t) d->get_axis();
341  }
342  return (axis_mask_t) modes;
343 }
344 
346  return currentDamping[(uint8_t) single_axis];
347 }
348 
349 void set_damping(axis_mask_t axisMask, damping_t damp) {
350  uint8_t j = 1;
351  axis_mask_t active_axis = get_active_axis();
352  for (uint8_t i = 0; i < (uint8_t) axis_mask_t::MAX; i++) {
353  j=1<<i;
354  if ((uint8_t) axisMask & j & (uint8_t) active_axis) {
355  currentDamping[j] = damp;
356  }
357  }
358 }
359 }}
Definition: comm.cpp:14
uint8_t test_sensor()
test whenever the sensors are connected, sensor should be horizontal and facing up.
Definition: movement.cpp:291
void set_velocity(axis_mask_t axisMask, int16_t mm_per_second)
Set the target velocity of the ROV.
Definition: movement.cpp:333
int debug(const char *format,...)
log debug message
Definition: log.cpp:51
void calibrate_sensors()
Calibarte the sensors, aka set 0 point.
Definition: movement.cpp:287
const std::map< err_t, char * > err_to_char
Definition: arunaTypes.h:54
int16_t get_speed(axis_mask_t single_axis)
Get the speed of an axis.
Definition: movement.cpp:314
status_t get_status()
get the status of the movement unit.
Definition: movement.cpp:56
int16_t get_velocity(axis_mask_t single_axis)
get the current velocity
Definition: movement.cpp:318
int16_t get_degree(axis_mask_t single_axis)
get the angle of an axis (pitch, roll and yaw only)
Definition: movement.cpp:322
err_t send(port_t to_port, uint8_t *data, size_t data_size, bool wait_for_ack=false)
Definition: comm.cpp:513
void set_damping(axis_mask_t axisMask, damping_t damp)
set the damping type.
Definition: movement.cpp:349
void * comm_handler_task(void *arg)
task to handle all the incoming comm requests.
Definition: movement.cpp:60
port_t from_port
channel who is sending the data.
Definition: commTypes.h:44
bool receive(transmitpackage_t *tpp)
handeler to handle incomming connections
Definition: commTypes.h:171
void set_degree(axis_mask_t axisMask, int16_t degree)
set the degree of an axis (only applies to yaw, pitch and roll)
Definition: movement.cpp:329
status_t stop()
Stop all motors and free all processes.
Definition: movement.cpp:263
Link * driver
stores the driver.
Definition: comm.cpp:45
int verbose(const char *format,...)
log verbose message
Definition: log.cpp:38
damping_t get_damping(axis_mask_t single_axis)
get the damping of a single mode.
Definition: movement.cpp:345
endpoint type of a comm channel
Definition: commTypes.h:150
int warning(const char *format,...)
log warning message
Definition: log.cpp:77
int error(const char *format,...)
log error message
Definition: log.cpp:90
axis_mask_t get_active_axis()
Get active modus (X,Y,Z,yawn,pitch,roll)
Definition: movement.cpp:337
err_t register_driver(Actuator *driver)
register a accelerator driver for use.
Definition: movement.cpp:278
void set_speed(axis_mask_t axisMask, int16_t speed)
Set the speed of the motors directly.
Definition: movement.cpp:296
status_t start()
initialise movement and communicate with hardware for active modes.
Definition: movement.cpp:30
const port_t port
port nr.
Definition: commTypes.h:164
uint8_t * data_received
pointer to where incoming data must be stored.
Definition: commTypes.h:65
transmit ready package.
Definition: commTypes.h:39