MotorController
orientation.c
1 #include "orientation.h"
2 #include "position.h"
3 #include "imudriver.h"
4 #include "tr_types.h"
5 #include "settings.h"
6 
7 #include "RTT/SEGGER_RTT.h"
8 
9 /******************************************************************************/
10 /* Local macros */
11 /******************************************************************************/
12 #define PITCH_MIN_VALUE -2880
13 #define PITCH_RANGE 5760
14 #define PITCH_MAX_VALUE 2880
15 
16 #define ROLL_MIN_VALUE -1440
17 #define ROLL_RANGE 2880
18 #define ROLL_MAX_VALUE 1440
19 
20 #define RAD_TO_DEG 57
21 
22 /******************************************************************************/
23 /* Local variables */
24 /******************************************************************************/
25 static int16_t pitch_offset = 0;
26 static int16_t roll_offset = 0;
27 
28 /******************************************************************************/
29 /* Public variables */
30 /******************************************************************************/
31 int16_t heading_offset = 0;
32 int16_t orientation;
33 int16_t delta_alpha;
34 
35 /******************************************************************************/
36 /* Public functions */
37 /******************************************************************************/
38 extern int32_t set_orientation(int16_t new_orientation)
39 {
40  int32_t status;
41  int16_t tmp[5];
42  int16_t average;
43  uint8_t i;
44 
45  if ((new_orientation >= HEADING_MIN_VALUE) && (new_orientation < HEADING_MAX_VALUE)) {
46  new_orientation = HEADING_MAX_VALUE - new_orientation; // change back to non-trigonometric orientation
47  do {
48  average = 0;
49  for (i = 0; i < 5; ++i) {
50  tmp[i] = getHeading();
51  average += tmp[i];
52  }
53  average /= 5;
54  } while (average != tmp[0]);
55 
56  heading_offset = average - new_orientation;
57  status = NO_ERROR;
58  } else {
59  status = INVALID_PARAMETER;
60  }
61 
62  return status;
63 }
64 
65 extern int16_t get_relative_heading(void)
66 {
67  int16_t heading;
68  int16_t direction;
69  static int16_t prev_direction;
70 
71  heading = getHeading();
72  if (ANGLE_ERROR == heading) {
73  direction = prev_direction;
74  } else {
75  direction = heading - heading_offset;
76  if (direction < HEADING_MIN_VALUE) {
77  direction += HEADING_RANGE;
78  } else if (direction > HEADING_MAX_VALUE) {
79  direction -= HEADING_RANGE;
80  }
81 
82  // Change the sense of the angle to have it trigonometric.
83  direction = HEADING_MAX_VALUE - direction;
84  prev_direction = direction;
85  }
86 
87  return direction;
88 }
89 
90 extern int32_t set_pitch(int16_t pitch) {
91  int32_t status;
92  int16_t tmp[5];
93  int16_t average;
94  uint8_t i;
95 
96  if ((pitch >= PITCH_MIN_VALUE) && (pitch < PITCH_MAX_VALUE)) {
97  do {
98  average = 0;
99  for (i = 0; i < 5; i++) {
100  tmp[i] = getPitch();
101  average += tmp[i];
102  }
103  average /= 5;
104  } while (average != tmp[0]);
105 
106  pitch_offset = average - pitch;
107  status = NO_ERROR;
108  } else {
109  status = INVALID_PARAMETER;
110  }
111 
112  return status;
113 }
114 
115 extern int16_t get_relative_pitch(void) {
116  int16_t pitch;
117 
118  pitch = getPitch();
119  if (pitch != ANGLE_ERROR) {
120  pitch -= pitch_offset;
121  if (pitch < PITCH_MIN_VALUE) {
122  pitch += PITCH_RANGE;
123  }
124  }
125 
126  return pitch;
127 }
128 
129 
130 extern int32_t set_roll(int16_t roll) {
131  int32_t status;
132  int16_t tmp[5];
133  int16_t average;
134  uint8_t i;
135 
136  if ((roll >= ROLL_MIN_VALUE) && (roll < ROLL_MAX_VALUE)) {
137  do {
138  average = 0;
139  for (i = 0; i < 5; i++) {
140  tmp[i] = getRoll();
141  average += tmp[i];
142  }
143  average /= 5;
144  } while (average != tmp[0]);
145 
146  roll_offset = average - roll;
147  status = NO_ERROR;
148  } else {
149  status = INVALID_PARAMETER;
150  }
151 
152  return status;
153 }
154 
155 extern int16_t get_relative_roll(void) {
156  int16_t roll;
157 
158  roll = getRoll();
159  if (roll != ANGLE_ERROR) {
160  roll -= roll_offset;
161  if (roll < ROLL_MIN_VALUE) {
162  roll += ROLL_RANGE;
163  }
164  }
165 
166  return roll;
167 }
168 
169 extern void update_orientation(void)
170 {
171  static uint32_t prev_time = 0U;
172  uint32_t cur_time;
173  uint32_t delta_time;
174  int16_t tmp_speed;
175 
176  cur_time = chVTGetSystemTime();
177 
178  if (0U != prev_time) {
179  delta_time = cur_time - prev_time;
180 
181  /* Compute delta alpha in radian */
182  delta_alpha = (int16_t)(delta_ticks.right - delta_ticks.left) * 100 / (settings.wheels_gap * settings.ticks_per_m);
183 
184  /* Compute local angular speed in °.s-1 */
185  tmp_speed = delta_alpha * RAD_TO_DEG / ST2S(delta_time);
186 
187  /* If variation is fast, don't use the IMU */
188  if ((tmp_speed <= -settings.angular_trust_threshold) || (tmp_speed >= settings.angular_trust_threshold)) {
189  orientation += delta_alpha * ANGLE_MULT_RAD;
190 
191  if (orientation < 0) {
192  orientation += HEADING_MAX_VALUE;
193  }
194 
195  orientation %= HEADING_MAX_VALUE;
196  } else { /* Small variation, use IMU as it's more precise */
198  }
199  } else {
200  /* First call to this function */
202  }
203 
204  prev_time = cur_time;
205 }
ticks_t delta_ticks
Definition: position.c:20
int32_t set_roll(int16_t roll)
Set the euler roll angle offset.
Definition: orientation.c:130
int16_t orientation
Definition: orientation.c:32
void update_orientation(void)
Update the current orientation.
Definition: orientation.c:169
int16_t get_relative_roll(void)
Get the relative roll angle (relative to the last setting).
Definition: orientation.c:155
int16_t get_relative_heading(void)
Get the relative heading (relative to the last setting) in trigo sense.
Definition: orientation.c:65
uint16_t wheels_gap
Definition: settings.h:41
int16_t heading_offset
Definition: orientation.c:31
int32_t set_pitch(int16_t pitch)
Set the euler pitch angle offset.
Definition: orientation.c:90
uint16_t angular_trust_threshold
Definition: settings.h:43
int32_t set_orientation(int16_t heading)
Set the euler heading angle offset.
Definition: orientation.c:38
uint16_t ticks_per_m
Definition: settings.h:42
int16_t get_relative_pitch(void)
Get the relative pitch angle (relative to the last setting).
Definition: orientation.c:115
volatile robot_settings_t settings
Global variable used to store the configuration in use.
Definition: settings.c:9