Cheetah Software  1.0
rt_vectornav.cpp
Go to the documentation of this file.
1 #include <inttypes.h>
2 #include <pthread.h>
3 #include <stdio.h>
4 #include <string>
5 
7 #include <lcm/lcm-cpp.hpp>
8 #include <stdexcept>
9 #include "Utilities/utilities.h"
10 #include "rt/rt_vectornav.h"
11 #include "vectornav_lcmt.hpp"
12 
13 #define K_MINI_CHEETAH_VECTOR_NAV_SERIAL "/dev/ttyS0"
14 
15 //#define PRINT_VECTORNAV_DEBUG
16 
17 int processErrorReceived(const std::string& errorMessage, VnError errorCode);
18 void vectornav_handler(void* userData, VnUartPacket* packet,
19  size_t running_index);
20 
21 typedef struct {
22  VnSensor vs;
23  BinaryOutputRegister bor;
24 } vn_sensor;
25 
27 
28 static lcm::LCM* vectornav_lcm;
29 vectornav_lcmt vectornav_lcm_data;
30 
31 static VectorNavData* g_vn_data = nullptr;
32 bool init_vectornav(VectorNavData* vn_data) {
33  g_vn_data = vn_data;
34  printf("[Simulation] Setup LCM...\n");
35  vectornav_lcm = new lcm::LCM(getLcmUrl(255));
36  if (!vectornav_lcm->good()) {
37  printf("[ERROR] Failed to set up LCM\n");
38  throw std::runtime_error("lcm bad");
39  }
40 
41  VnError error;
42  VpeBasicControlRegister vpeReg;
43  ImuFilteringConfigurationRegister filtReg;
44  const char SENSOR_PORT[] = K_MINI_CHEETAH_VECTOR_NAV_SERIAL;
45  const uint32_t SENSOR_BAUDRATE = 115200;
46  char modelNumber[30];
47  char strConversions[50];
48  uint32_t newHz, oldHz;
49  // uint32_t hz_desired = 200;
50 
51  printf("[rt_vectornav] init_vectornav()\n");
52 
53  // initialize vectornav library
54  VnSensor_initialize(&(vn.vs));
55 
56  // connect to sensor
57  if ((error = VnSensor_connect(&(vn.vs), SENSOR_PORT, SENSOR_BAUDRATE)) !=
58  E_NONE) {
59  printf("[rt_vectornav] VnSensor_connect failed.\n");
60  processErrorReceived("Error connecting to sensor.", error);
61  return false;
62  }
63 
64  // read the sensor's model number
65  if ((error = VnSensor_readModelNumber(&(vn.vs), modelNumber,
66  sizeof(modelNumber))) != E_NONE) {
67  printf("[rt_vectornav] VnSensor_readModelNumber failed.\n");
68  processErrorReceived("Error reading model number.", error);
69  return false;
70  }
71  printf("Model Number: %s\n", modelNumber);
72 
73  // switch the sensor to 1 kHz mode
74  if ((error = VnSensor_readAsyncDataOutputFrequency(&(vn.vs), &oldHz)) !=
75  E_NONE) {
76  printf("[rt_vectornav] VnSensor_readAsyncDataOutputFrequency failed.\n");
77  processErrorReceived("Error reading async data output frequency.", error);
78  return false;
79  }
80 
81  // non-zero frequency causes the IMU to output ascii packets at the set
82  // frequency, as well as binary
83  if ((error = VnSensor_writeAsyncDataOutputFrequency(&(vn.vs), 0, true)) !=
84  E_NONE) {
85  printf("[rt_vectornav] VnSensor_wrtieAsyncDataOutputFrequency failed.\n");
86  processErrorReceived("Error writing async data output frequency.", error);
87  return false;
88  }
89  if ((error = VnSensor_readAsyncDataOutputFrequency(&(vn.vs), &newHz)) !=
90  E_NONE) {
91  printf("[rt_vectornav] VnSensor_readAsyncDataOutputFrequency failed.\n");
92  processErrorReceived("Error reading async data output frequency.", error);
93  return false;
94  }
95  printf("[rt_vectornav] Changed frequency from %d to %d Hz.\n", oldHz, newHz);
96 
97  // change to relative heading mode to avoid compass weirdness
98  if ((error = VnSensor_readVpeBasicControl(&(vn.vs), &vpeReg)) != E_NONE) {
99  printf("[rt_vectornav] VnSensor_ReadVpeBasicControl failed.\n");
100  processErrorReceived("Error reading VPE basic control.", error);
101  return false;
102  }
103  strFromHeadingMode(strConversions, (VnHeadingMode)vpeReg.headingMode);
104  printf("[rt_vectornav] Sensor was in mode: %s\n", strConversions);
105  vpeReg.headingMode = VNHEADINGMODE_RELATIVE;
106  if ((error = VnSensor_writeVpeBasicControl(&(vn.vs), vpeReg, true)) !=
107  E_NONE) {
108  printf("[rt_vectornav] VnSensor_writeVpeBasicControl failed.\n");
109  processErrorReceived("Error writing VPE basic control.", error);
110  return false;
111  }
112  if ((error = VnSensor_readVpeBasicControl(&(vn.vs), &vpeReg)) != E_NONE) {
113  processErrorReceived("Error reading VPE basic control.", error);
114  printf("[rt_vectornav] VnSensor_ReadVpeBasicControl failed.\n");
115  return false;
116  }
117  strFromHeadingMode(strConversions, (VnHeadingMode)vpeReg.headingMode);
118  printf("[rt_vectornav] Sensor now id mode: %s\n", strConversions);
119 
120  if ((error = VnSensor_readImuFilteringConfiguration(&(vn.vs), &filtReg)) !=
121  E_NONE) {
122  printf("[rt_vectornav] VnSensor_readGyroCompensation failed.\n");
123  }
124  printf("[rt_vectornav] AccelWindow: %d\n", filtReg.accelWindowSize);
125  // filtReg.accelWindowSize = 4; // We're sampling at 200 hz, but the
126  // imu samples at 800 hz. filtReg.accelFilterMode = 3; if((error =
127  // VnSensor_writeImuFilteringConfiguration(&(vn.vs), filtReg, true)) !=
128  // E_NONE)
129  // {
130  // printf("[rt_vectornav] VnSensor_writeGyroCompensation
131  // failed.\n");
132  // }
133 
134  // setup binary output message type
135  BinaryOutputRegister_initialize(
136  &(vn.bor), ASYNCMODE_PORT2,
137  4, // divisor: output frequency = 800/divisor
138  (CommonGroup)(COMMONGROUP_QUATERNION | COMMONGROUP_ANGULARRATE |
139  COMMONGROUP_ACCEL),
140  TIMEGROUP_NONE, IMUGROUP_NONE, GPSGROUP_NONE, ATTITUDEGROUP_NONE,
141  INSGROUP_NONE, GPSGROUP_NONE);
142 
143  if ((error = VnSensor_writeBinaryOutput1(&(vn.vs), &(vn.bor), true)) !=
144  E_NONE) {
145  printf("[rt_vectornav] VnSensor_writeBinaryOutput1 failed.\n");
146  processErrorReceived("Error writing binary output 1.", error);
147  return false;
148  }
149 
150  // setup handler
151  VnSensor_registerAsyncPacketReceivedHandler(&(vn.vs), vectornav_handler,
152  NULL);
153  printf("[rt_vectornav] IMU is set up!\n");
154  return true;
155 }
156 
158 void vectornav_handler(void* userData, VnUartPacket* packet,
159  size_t running_index) {
160  (void)userData;
161  (void)running_index;
162  vec4f quat;
163  vec3f omega;
164  vec3f a;
165 
166  if (VnUartPacket_type(packet) != PACKETTYPE_BINARY) {
167  printf("[vectornav_handler] got a packet that wasn't binary.\n");
168  return;
169  }
170 
171  if (!VnUartPacket_isCompatible(
172  packet,
173  (CommonGroup)(COMMONGROUP_QUATERNION | COMMONGROUP_ANGULARRATE |
174  COMMONGROUP_ACCEL),
175  TIMEGROUP_NONE, IMUGROUP_NONE, GPSGROUP_NONE, ATTITUDEGROUP_NONE,
176  INSGROUP_NONE, GPSGROUP_NONE)) {
177  printf("[vectornav_handler] got a packet with the wrong type of data.\n");
178  return;
179  }
180 
181  quat = VnUartPacket_extractVec4f(packet);
182  omega = VnUartPacket_extractVec3f(packet);
183  a = VnUartPacket_extractVec3f(packet);
184 
185  for (int i = 0; i < 4; i++) {
186  vectornav_lcm_data.q[i] = quat.c[i];
187  g_vn_data->quat[i] = quat.c[i];
188  }
189 
190  for (int i = 0; i < 3; i++) {
191  vectornav_lcm_data.w[i] = omega.c[i];
192  vectornav_lcm_data.a[i] = a.c[i];
193  g_vn_data->gyro[i] = omega.c[i];
194  g_vn_data->accelerometer[i] = a.c[i];
195  }
196 
197  vectornav_lcm->publish("hw_vectornav", &vectornav_lcm_data);
198 
199 #ifdef PRINT_VECTORNAV_DEBUG
200  char strConversions[50];
201  str_vec4f(strConversions, quat);
202  printf("[QUAT] %s\n", strConversions);
203 
204  str_vec3f(strConversions, omega);
205  printf("[OMEGA] %s\n", strConversions);
206 
207  str_vec3f(strConversions, a);
208  printf("[ACC] %s\n", strConversions);
209 #endif
210 }
211 
212 int processErrorReceived(const std::string& errorMessage, VnError errorCode) {
213  char errorCodeStr[100];
214  strFromVnError(errorCodeStr, errorCode);
215  printf("%s\nVECTORNAV ERROR: %s\n", errorMessage.c_str(), errorCodeStr);
216  return -1;
217 }
int processErrorReceived(const std::string &errorMessage, VnError errorCode)
#define K_MINI_CHEETAH_VECTOR_NAV_SERIAL
VnSensor vs
static VectorNavData * g_vn_data
std::string getLcmUrl(s64 ttl)
Definition: utilities.cpp:32
Vec3< float > accelerometer
Definition: IMUTypes.h:14
vn_sensor vn
bool init_vectornav(VectorNavData *vn_data)
vectornav_lcmt vectornav_lcm_data
Quat< float > quat
Definition: IMUTypes.h:16
void vectornav_handler(void *userData, VnUartPacket *packet, size_t running_index)
static lcm::LCM * vectornav_lcm
Data from IMUs.
Vec3< float > gyro
Definition: IMUTypes.h:15
BinaryOutputRegister bor
int got_first_vectornav_message