lib
Dependencies: mbed ros_lib_indigo
main.cpp@0:c94b2f0a4409, 2017-10-02 (annotated)
- Committer:
- tea5062001
- Date:
- Mon Oct 02 11:30:47 2017 +0000
- Revision:
- 0:c94b2f0a4409
lib
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
tea5062001 | 0:c94b2f0a4409 | 1 | #include "mbed.h" |
tea5062001 | 0:c94b2f0a4409 | 2 | #include "led.h" |
tea5062001 | 0:c94b2f0a4409 | 3 | #include "uart_send.h" |
tea5062001 | 0:c94b2f0a4409 | 4 | #include <ros.h> |
tea5062001 | 0:c94b2f0a4409 | 5 | #include <geometry_msgs/Vector3.h> |
tea5062001 | 0:c94b2f0a4409 | 6 | #include <geometry_msgs/Twist.h> |
tea5062001 | 0:c94b2f0a4409 | 7 | #include "LSM9DS0_SH.h" |
tea5062001 | 0:c94b2f0a4409 | 8 | #include <math.h> |
tea5062001 | 0:c94b2f0a4409 | 9 | |
tea5062001 | 0:c94b2f0a4409 | 10 | #define r_01 ((double)rand()/(RAND_MAX)) // uniform distribution 0 ~ 1 |
tea5062001 | 0:c94b2f0a4409 | 11 | #define constrain(amt,low,high) ((amt)<(low) ? (low) : ((amt) > (high) ? (high) : (amt))) |
tea5062001 | 0:c94b2f0a4409 | 12 | |
tea5062001 | 0:c94b2f0a4409 | 13 | // timer 1 : sensor fusion |
tea5062001 | 0:c94b2f0a4409 | 14 | #define LOOPTIME 2000 // 0.002 s |
tea5062001 | 0:c94b2f0a4409 | 15 | unsigned long lastMilli = 0; |
tea5062001 | 0:c94b2f0a4409 | 16 | // sampling time |
tea5062001 | 0:c94b2f0a4409 | 17 | float T = 0.002; |
tea5062001 | 0:c94b2f0a4409 | 18 | |
tea5062001 | 0:c94b2f0a4409 | 19 | // timer 2 : publish cmd_vel for mag_cor |
tea5062001 | 0:c94b2f0a4409 | 20 | #define LOOPTIME2 100000 // 0.1 s |
tea5062001 | 0:c94b2f0a4409 | 21 | unsigned long lastMilli2 = 0; |
tea5062001 | 0:c94b2f0a4409 | 22 | |
tea5062001 | 0:c94b2f0a4409 | 23 | // timer 3 : take part of mag data |
tea5062001 | 0:c94b2f0a4409 | 24 | #define LOOPTIME3 300000 // 0.3 s |
tea5062001 | 0:c94b2f0a4409 | 25 | unsigned long lastMilli3 = 0; |
tea5062001 | 0:c94b2f0a4409 | 26 | |
tea5062001 | 0:c94b2f0a4409 | 27 | // timer 5 : extended kalman filter |
tea5062001 | 0:c94b2f0a4409 | 28 | #define LOOPTIME5 20000 // 0.02 s |
tea5062001 | 0:c94b2f0a4409 | 29 | unsigned long lastMilli5 = 0; |
tea5062001 | 0:c94b2f0a4409 | 30 | // sampling time |
tea5062001 | 0:c94b2f0a4409 | 31 | float T2 = 0.02; |
tea5062001 | 0:c94b2f0a4409 | 32 | |
tea5062001 | 0:c94b2f0a4409 | 33 | // timer 6 : navigation |
tea5062001 | 0:c94b2f0a4409 | 34 | #define LOOPTIME6 100000 // 0.1 s |
tea5062001 | 0:c94b2f0a4409 | 35 | unsigned long lastMilli6 = 0; |
tea5062001 | 0:c94b2f0a4409 | 36 | |
tea5062001 | 0:c94b2f0a4409 | 37 | Timer t; |
tea5062001 | 0:c94b2f0a4409 | 38 | |
tea5062001 | 0:c94b2f0a4409 | 39 | ros::NodeHandle nh; |
tea5062001 | 0:c94b2f0a4409 | 40 | |
tea5062001 | 0:c94b2f0a4409 | 41 | geometry_msgs::Twist vel_msg; |
tea5062001 | 0:c94b2f0a4409 | 42 | ros::Publisher p("andbot/cmd_vel", &vel_msg); |
tea5062001 | 0:c94b2f0a4409 | 43 | unsigned long current_time = 0; |
tea5062001 | 0:c94b2f0a4409 | 44 | unsigned long last_time = 0; |
tea5062001 | 0:c94b2f0a4409 | 45 | |
tea5062001 | 0:c94b2f0a4409 | 46 | // car information |
tea5062001 | 0:c94b2f0a4409 | 47 | double wheelRadius = 0.078; |
tea5062001 | 0:c94b2f0a4409 | 48 | double wheelSeparation = 0.393; |
tea5062001 | 0:c94b2f0a4409 | 49 | double omega_right = 0.0; |
tea5062001 | 0:c94b2f0a4409 | 50 | double omega_left = 0.0; |
tea5062001 | 0:c94b2f0a4409 | 51 | double omega_z = 0.0; |
tea5062001 | 0:c94b2f0a4409 | 52 | double vel_x = 0.0; |
tea5062001 | 0:c94b2f0a4409 | 53 | double th = 0.0; |
tea5062001 | 0:c94b2f0a4409 | 54 | int th_deg = 0; |
tea5062001 | 0:c94b2f0a4409 | 55 | double x = 0.0; |
tea5062001 | 0:c94b2f0a4409 | 56 | double y_ = 0.0; |
tea5062001 | 0:c94b2f0a4409 | 57 | |
tea5062001 | 0:c94b2f0a4409 | 58 | // start car rotation for magnetometer correction flag |
tea5062001 | 0:c94b2f0a4409 | 59 | int check_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 60 | |
tea5062001 | 0:c94b2f0a4409 | 61 | // magnetometer correction data |
tea5062001 | 0:c94b2f0a4409 | 62 | // magnetometer 1 |
tea5062001 | 0:c94b2f0a4409 | 63 | float magx[100] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 64 | float magy[100] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 65 | int ind = 0; |
tea5062001 | 0:c94b2f0a4409 | 66 | int ind_ = 0; |
tea5062001 | 0:c94b2f0a4409 | 67 | float cal_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 68 | float magx_max = 0; |
tea5062001 | 0:c94b2f0a4409 | 69 | float magx_min = 0; |
tea5062001 | 0:c94b2f0a4409 | 70 | float magx0 = 0; |
tea5062001 | 0:c94b2f0a4409 | 71 | float magy_max = 0; |
tea5062001 | 0:c94b2f0a4409 | 72 | float magy_min = 0; |
tea5062001 | 0:c94b2f0a4409 | 73 | float magy0 = 0; |
tea5062001 | 0:c94b2f0a4409 | 74 | float a = 0.3324; // long axis |
tea5062001 | 0:c94b2f0a4409 | 75 | float b = 0.3082; // short axis |
tea5062001 | 0:c94b2f0a4409 | 76 | |
tea5062001 | 0:c94b2f0a4409 | 77 | // magnetometer 2 |
tea5062001 | 0:c94b2f0a4409 | 78 | float magx2[100] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 79 | float magy2[100] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 80 | float magx_max2 = 0; |
tea5062001 | 0:c94b2f0a4409 | 81 | float magx_min2 = 0; |
tea5062001 | 0:c94b2f0a4409 | 82 | float magx02 = 0; |
tea5062001 | 0:c94b2f0a4409 | 83 | float magy_max2 = 0; |
tea5062001 | 0:c94b2f0a4409 | 84 | float magy_min2 = 0; |
tea5062001 | 0:c94b2f0a4409 | 85 | float magy02 = 0; |
tea5062001 | 0:c94b2f0a4409 | 86 | float a2 = 0.3366; // long axis |
tea5062001 | 0:c94b2f0a4409 | 87 | float b2 = 0.3312; // short axis |
tea5062001 | 0:c94b2f0a4409 | 88 | |
tea5062001 | 0:c94b2f0a4409 | 89 | // vision data |
tea5062001 | 0:c94b2f0a4409 | 90 | int px = 0; |
tea5062001 | 0:c94b2f0a4409 | 91 | int py = 0; |
tea5062001 | 0:c94b2f0a4409 | 92 | int vision_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 93 | // calibration parameter |
tea5062001 | 0:c94b2f0a4409 | 94 | float alpha_u = 179.869823; |
tea5062001 | 0:c94b2f0a4409 | 95 | float alpha_v = 179.984858; |
tea5062001 | 0:c94b2f0a4409 | 96 | float alpha_s = 0; |
tea5062001 | 0:c94b2f0a4409 | 97 | float cx = 81.709410; |
tea5062001 | 0:c94b2f0a4409 | 98 | float cy = 64.218079; |
tea5062001 | 0:c94b2f0a4409 | 99 | // c : camera coordinate |
tea5062001 | 0:c94b2f0a4409 | 100 | float Zc = 420; // unit : mm |
tea5062001 | 0:c94b2f0a4409 | 101 | float Xc = 0; |
tea5062001 | 0:c94b2f0a4409 | 102 | float Yc = 0; |
tea5062001 | 0:c94b2f0a4409 | 103 | float Theta_c = 0; |
tea5062001 | 0:c94b2f0a4409 | 104 | // r : robot coordinate |
tea5062001 | 0:c94b2f0a4409 | 105 | float Xr = 0; |
tea5062001 | 0:c94b2f0a4409 | 106 | float Yr = 0; |
tea5062001 | 0:c94b2f0a4409 | 107 | // from odometry and cross detection to predict map coordinate |
tea5062001 | 0:c94b2f0a4409 | 108 | float Xp = 0; |
tea5062001 | 0:c94b2f0a4409 | 109 | float Yp = 0; |
tea5062001 | 0:c94b2f0a4409 | 110 | |
tea5062001 | 0:c94b2f0a4409 | 111 | // subscribe feedback_wheel_angularVel |
tea5062001 | 0:c94b2f0a4409 | 112 | void messageCb(const geometry_msgs::Vector3& msg) |
tea5062001 | 0:c94b2f0a4409 | 113 | { |
tea5062001 | 0:c94b2f0a4409 | 114 | Y_ = !Y_; |
tea5062001 | 0:c94b2f0a4409 | 115 | |
tea5062001 | 0:c94b2f0a4409 | 116 | omega_left = msg.x; |
tea5062001 | 0:c94b2f0a4409 | 117 | omega_right = msg.y; |
tea5062001 | 0:c94b2f0a4409 | 118 | |
tea5062001 | 0:c94b2f0a4409 | 119 | omega_z = wheelRadius * (omega_right - omega_left) / wheelSeparation; |
tea5062001 | 0:c94b2f0a4409 | 120 | vel_x = wheelRadius * (omega_right + omega_left) / 2; |
tea5062001 | 0:c94b2f0a4409 | 121 | |
tea5062001 | 0:c94b2f0a4409 | 122 | current_time = t.read_ms(); |
tea5062001 | 0:c94b2f0a4409 | 123 | double dt = (current_time - last_time) * 0.001; // from ms to s |
tea5062001 | 0:c94b2f0a4409 | 124 | last_time = current_time; |
tea5062001 | 0:c94b2f0a4409 | 125 | |
tea5062001 | 0:c94b2f0a4409 | 126 | double delta_th = omega_z * dt; |
tea5062001 | 0:c94b2f0a4409 | 127 | th += delta_th; |
tea5062001 | 0:c94b2f0a4409 | 128 | |
tea5062001 | 0:c94b2f0a4409 | 129 | double delta_x = vel_x * cos(th) * dt; |
tea5062001 | 0:c94b2f0a4409 | 130 | x += delta_x; |
tea5062001 | 0:c94b2f0a4409 | 131 | |
tea5062001 | 0:c94b2f0a4409 | 132 | double delta_y = vel_x * sin(th) * dt; |
tea5062001 | 0:c94b2f0a4409 | 133 | y_ += delta_y; |
tea5062001 | 0:c94b2f0a4409 | 134 | |
tea5062001 | 0:c94b2f0a4409 | 135 | // for mag_cor |
tea5062001 | 0:c94b2f0a4409 | 136 | if(check_flag == 1) |
tea5062001 | 0:c94b2f0a4409 | 137 | { |
tea5062001 | 0:c94b2f0a4409 | 138 | if(th >= 2*PI) |
tea5062001 | 0:c94b2f0a4409 | 139 | { |
tea5062001 | 0:c94b2f0a4409 | 140 | check_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 141 | cal_flag = 1; |
tea5062001 | 0:c94b2f0a4409 | 142 | vel_msg.angular.z = 0.0; |
tea5062001 | 0:c94b2f0a4409 | 143 | p.publish(&vel_msg); |
tea5062001 | 0:c94b2f0a4409 | 144 | th = 0; |
tea5062001 | 0:c94b2f0a4409 | 145 | } |
tea5062001 | 0:c94b2f0a4409 | 146 | } |
tea5062001 | 0:c94b2f0a4409 | 147 | } |
tea5062001 | 0:c94b2f0a4409 | 148 | |
tea5062001 | 0:c94b2f0a4409 | 149 | ros::Subscriber<geometry_msgs::Vector3> s("feedback_wheel_angularVel",messageCb); |
tea5062001 | 0:c94b2f0a4409 | 150 | |
tea5062001 | 0:c94b2f0a4409 | 151 | int update_source = 0; |
tea5062001 | 0:c94b2f0a4409 | 152 | |
tea5062001 | 0:c94b2f0a4409 | 153 | // subscribe point |
tea5062001 | 0:c94b2f0a4409 | 154 | void messageCb2(const geometry_msgs::Vector3& pp) |
tea5062001 | 0:c94b2f0a4409 | 155 | { |
tea5062001 | 0:c94b2f0a4409 | 156 | px = pp.x; |
tea5062001 | 0:c94b2f0a4409 | 157 | py = pp.y; |
tea5062001 | 0:c94b2f0a4409 | 158 | Theta_c = pp.z; |
tea5062001 | 0:c94b2f0a4409 | 159 | |
tea5062001 | 0:c94b2f0a4409 | 160 | if(px != 0 || py != 0 || Theta_c != 0) |
tea5062001 | 0:c94b2f0a4409 | 161 | vision_flag = 1; |
tea5062001 | 0:c94b2f0a4409 | 162 | else |
tea5062001 | 0:c94b2f0a4409 | 163 | vision_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 164 | |
tea5062001 | 0:c94b2f0a4409 | 165 | if(vision_flag == 1 && px > 0 && py > 0) |
tea5062001 | 0:c94b2f0a4409 | 166 | { |
tea5062001 | 0:c94b2f0a4409 | 167 | // from image plane coordinate to camera coordinate |
tea5062001 | 0:c94b2f0a4409 | 168 | Xc = (Zc/alpha_u)*(px - cx) - ((alpha_s*Zc)/(alpha_u*alpha_v))*(py - cy); |
tea5062001 | 0:c94b2f0a4409 | 169 | Yc = (Zc/alpha_v)*(py - cy); |
tea5062001 | 0:c94b2f0a4409 | 170 | |
tea5062001 | 0:c94b2f0a4409 | 171 | // from camera coordinate to robot coordinate |
tea5062001 | 0:c94b2f0a4409 | 172 | Xr = -Yc + 175; |
tea5062001 | 0:c94b2f0a4409 | 173 | Yr = -Xc - 10; |
tea5062001 | 0:c94b2f0a4409 | 174 | |
tea5062001 | 0:c94b2f0a4409 | 175 | // change unit to meter |
tea5062001 | 0:c94b2f0a4409 | 176 | Xr = Xr * 0.001; |
tea5062001 | 0:c94b2f0a4409 | 177 | Yr = Yr * 0.001; |
tea5062001 | 0:c94b2f0a4409 | 178 | |
tea5062001 | 0:c94b2f0a4409 | 179 | update_source = 1; |
tea5062001 | 0:c94b2f0a4409 | 180 | } |
tea5062001 | 0:c94b2f0a4409 | 181 | else if(vision_flag == 1 && px == 0 && py == 0 && ((Theta_c >= 1 && Theta_c <= 89) || (Theta_c >= -89 && Theta_c <= -1))) |
tea5062001 | 0:c94b2f0a4409 | 182 | { |
tea5062001 | 0:c94b2f0a4409 | 183 | update_source = 2; |
tea5062001 | 0:c94b2f0a4409 | 184 | } |
tea5062001 | 0:c94b2f0a4409 | 185 | else |
tea5062001 | 0:c94b2f0a4409 | 186 | { |
tea5062001 | 0:c94b2f0a4409 | 187 | Xr = 0; |
tea5062001 | 0:c94b2f0a4409 | 188 | Yr = 0; |
tea5062001 | 0:c94b2f0a4409 | 189 | |
tea5062001 | 0:c94b2f0a4409 | 190 | update_source = 0; |
tea5062001 | 0:c94b2f0a4409 | 191 | } |
tea5062001 | 0:c94b2f0a4409 | 192 | } |
tea5062001 | 0:c94b2f0a4409 | 193 | |
tea5062001 | 0:c94b2f0a4409 | 194 | ros::Subscriber<geometry_msgs::Vector3> s2("point",messageCb2); |
tea5062001 | 0:c94b2f0a4409 | 195 | |
tea5062001 | 0:c94b2f0a4409 | 196 | void read_sensor(void); |
tea5062001 | 0:c94b2f0a4409 | 197 | |
tea5062001 | 0:c94b2f0a4409 | 198 | float lpf(float input, float output_old, float frequency); |
tea5062001 | 0:c94b2f0a4409 | 199 | |
tea5062001 | 0:c94b2f0a4409 | 200 | int sensor_flag = 0; // sensor initial flag |
tea5062001 | 0:c94b2f0a4409 | 201 | int sensor_count = 0; |
tea5062001 | 0:c94b2f0a4409 | 202 | |
tea5062001 | 0:c94b2f0a4409 | 203 | // sensor filter correction data |
tea5062001 | 0:c94b2f0a4409 | 204 | float Gyro_axis_data_f[3]; |
tea5062001 | 0:c94b2f0a4409 | 205 | float Gyro_axis_data_f_old[3]; |
tea5062001 | 0:c94b2f0a4409 | 206 | float Gyro_scale[3]; // scale = (data - zero) |
tea5062001 | 0:c94b2f0a4409 | 207 | float Gyro_axis_zero[3] = {0,0,0}; // x,y no use |
tea5062001 | 0:c94b2f0a4409 | 208 | |
tea5062001 | 0:c94b2f0a4409 | 209 | // sensor 1 (front) |
tea5062001 | 0:c94b2f0a4409 | 210 | float Magn_axis_data_f[3]; |
tea5062001 | 0:c94b2f0a4409 | 211 | float Magn_axis_data_f_old[3]; |
tea5062001 | 0:c94b2f0a4409 | 212 | float Magn_scale[3]; // scale = (data - zero) |
tea5062001 | 0:c94b2f0a4409 | 213 | float Magn_axis_zero[3] = {-0.1049,0.1982,0}; |
tea5062001 | 0:c94b2f0a4409 | 214 | |
tea5062001 | 0:c94b2f0a4409 | 215 | // sensor 2 (back) |
tea5062001 | 0:c94b2f0a4409 | 216 | float Magn_axis_data_f2[3]; |
tea5062001 | 0:c94b2f0a4409 | 217 | float Magn_axis_data_f_old2[3]; |
tea5062001 | 0:c94b2f0a4409 | 218 | float Magn_scale2[3]; // scale = (data - zero) |
tea5062001 | 0:c94b2f0a4409 | 219 | float Magn_axis_zero2[3] = {0.1547,0.2713,0}; |
tea5062001 | 0:c94b2f0a4409 | 220 | |
tea5062001 | 0:c94b2f0a4409 | 221 | float Bex = 0; |
tea5062001 | 0:c94b2f0a4409 | 222 | float Bey = 0; |
tea5062001 | 0:c94b2f0a4409 | 223 | float Bex2 = 0; |
tea5062001 | 0:c94b2f0a4409 | 224 | float Bey2 = 0; |
tea5062001 | 0:c94b2f0a4409 | 225 | float Be = 0.9882; // Be = ( sqrt(Bex*Bex + Bey*Bey) + sqrt(Bex2*Bex2 + Bey2*Bey2) ) / 2 |
tea5062001 | 0:c94b2f0a4409 | 226 | |
tea5062001 | 0:c94b2f0a4409 | 227 | // counter for gyro bias |
tea5062001 | 0:c94b2f0a4409 | 228 | int gyro_count = 0; |
tea5062001 | 0:c94b2f0a4409 | 229 | int gyro_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 230 | float gyro_init[10] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 231 | int index_count = 0; |
tea5062001 | 0:c94b2f0a4409 | 232 | float gyro_sum = 0; |
tea5062001 | 0:c94b2f0a4409 | 233 | |
tea5062001 | 0:c94b2f0a4409 | 234 | // sensor data |
tea5062001 | 0:c94b2f0a4409 | 235 | // magn |
tea5062001 | 0:c94b2f0a4409 | 236 | float phi = 0; |
tea5062001 | 0:c94b2f0a4409 | 237 | float phi2 = 0; |
tea5062001 | 0:c94b2f0a4409 | 238 | int phi_init_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 239 | int phi_init_count = 0; |
tea5062001 | 0:c94b2f0a4409 | 240 | float phi_init = 0; |
tea5062001 | 0:c94b2f0a4409 | 241 | float phi_init2 = 0; |
tea5062001 | 0:c94b2f0a4409 | 242 | float phi_m = 0; |
tea5062001 | 0:c94b2f0a4409 | 243 | float phi_m2 = 0; |
tea5062001 | 0:c94b2f0a4409 | 244 | int phi_m_deg = 0; |
tea5062001 | 0:c94b2f0a4409 | 245 | int phi_m2_deg = 0; |
tea5062001 | 0:c94b2f0a4409 | 246 | int phi_m_deg_1 = 0; |
tea5062001 | 0:c94b2f0a4409 | 247 | int phi_m2_deg_1 = 0; |
tea5062001 | 0:c94b2f0a4409 | 248 | int phi_m_deg_2 = 0; |
tea5062001 | 0:c94b2f0a4409 | 249 | int phi_m2_deg_2 = 0; |
tea5062001 | 0:c94b2f0a4409 | 250 | int phi_m_deg_T = 0; |
tea5062001 | 0:c94b2f0a4409 | 251 | int phi_m2_deg_T = 0; |
tea5062001 | 0:c94b2f0a4409 | 252 | float phi_m_a = 0; |
tea5062001 | 0:c94b2f0a4409 | 253 | float phi_m2_a = 0; |
tea5062001 | 0:c94b2f0a4409 | 254 | int phi_m_a_deg = 0; |
tea5062001 | 0:c94b2f0a4409 | 255 | int phi_m2_a_deg = 0; |
tea5062001 | 0:c94b2f0a4409 | 256 | int diff_phi_count = 0; |
tea5062001 | 0:c94b2f0a4409 | 257 | int diff_phi_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 258 | int jump_count = 0; |
tea5062001 | 0:c94b2f0a4409 | 259 | int jump_count2 = 0; |
tea5062001 | 0:c94b2f0a4409 | 260 | float phi_m_a_avg = 0; |
tea5062001 | 0:c94b2f0a4409 | 261 | |
tea5062001 | 0:c94b2f0a4409 | 262 | // gyro |
tea5062001 | 0:c94b2f0a4409 | 263 | float w_s = 0; |
tea5062001 | 0:c94b2f0a4409 | 264 | float w_s_d = 0; |
tea5062001 | 0:c94b2f0a4409 | 265 | float theta_s = 0; |
tea5062001 | 0:c94b2f0a4409 | 266 | int theta_s_deg = 0; |
tea5062001 | 0:c94b2f0a4409 | 267 | |
tea5062001 | 0:c94b2f0a4409 | 268 | // fusion data for theta |
tea5062001 | 0:c94b2f0a4409 | 269 | float theta_fu = 0; |
tea5062001 | 0:c94b2f0a4409 | 270 | float theta_fu_old = 0; |
tea5062001 | 0:c94b2f0a4409 | 271 | float bias = 0; |
tea5062001 | 0:c94b2f0a4409 | 272 | float bias_old = 0; |
tea5062001 | 0:c94b2f0a4409 | 273 | float y = 0; |
tea5062001 | 0:c94b2f0a4409 | 274 | float L1 = 0; |
tea5062001 | 0:c94b2f0a4409 | 275 | float L2 = 0; |
tea5062001 | 0:c94b2f0a4409 | 276 | int fusion_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 277 | |
tea5062001 | 0:c94b2f0a4409 | 278 | // theta_fu to ROS |
tea5062001 | 0:c94b2f0a4409 | 279 | int theta_fu_deg = 0; |
tea5062001 | 0:c94b2f0a4409 | 280 | int theta_fu_deg_180 = 0; |
tea5062001 | 0:c94b2f0a4409 | 281 | float theta_fu_PI = 0; |
tea5062001 | 0:c94b2f0a4409 | 282 | |
tea5062001 | 0:c94b2f0a4409 | 283 | // add bias |
tea5062001 | 0:c94b2f0a4409 | 284 | int bias_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 285 | float bias_add = 0; |
tea5062001 | 0:c94b2f0a4409 | 286 | |
tea5062001 | 0:c94b2f0a4409 | 287 | // magnetic field disturbance detect |
tea5062001 | 0:c94b2f0a4409 | 288 | // trust index |
tea5062001 | 0:c94b2f0a4409 | 289 | float Q = 0; |
tea5062001 | 0:c94b2f0a4409 | 290 | // Kalman filter |
tea5062001 | 0:c94b2f0a4409 | 291 | float V = 0; // measurement noise variance |
tea5062001 | 0:c94b2f0a4409 | 292 | float theta_me = 0; |
tea5062001 | 0:c94b2f0a4409 | 293 | int theta_me_deg = 0; |
tea5062001 | 0:c94b2f0a4409 | 294 | float theta_me_bar = 0; |
tea5062001 | 0:c94b2f0a4409 | 295 | float sigma = 0; |
tea5062001 | 0:c94b2f0a4409 | 296 | float sigma_bar = 0; |
tea5062001 | 0:c94b2f0a4409 | 297 | float K = 0; // gain |
tea5062001 | 0:c94b2f0a4409 | 298 | float At = 1; |
tea5062001 | 0:c94b2f0a4409 | 299 | float Bt = 0.002; // sampling time |
tea5062001 | 0:c94b2f0a4409 | 300 | float Ct = 1; |
tea5062001 | 0:c94b2f0a4409 | 301 | float Rt = 0.001; // process noise variance |
tea5062001 | 0:c94b2f0a4409 | 302 | float update_distance = 0; |
tea5062001 | 0:c94b2f0a4409 | 303 | float update_rotation = 0; |
tea5062001 | 0:c94b2f0a4409 | 304 | int update_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 305 | |
tea5062001 | 0:c94b2f0a4409 | 306 | // extended kalman filter for localization |
tea5062001 | 0:c94b2f0a4409 | 307 | // EKF variables |
tea5062001 | 0:c94b2f0a4409 | 308 | // prediction variables |
tea5062001 | 0:c94b2f0a4409 | 309 | float mu_bar[3][1] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 310 | int mu_bar_deg = 0; |
tea5062001 | 0:c94b2f0a4409 | 311 | float mu[3][1] = {0}; // state vector |
tea5062001 | 0:c94b2f0a4409 | 312 | float Sigma_bar[3][3] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 313 | float Sigma[3][3] = { {0 , 0 , 0} , {0 , 0 , 0} , {0 , 0 , 0} }; // estimation covariance matrix |
tea5062001 | 0:c94b2f0a4409 | 314 | float Sigma_mul_1[3][3] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 315 | float Sigma_mul_2[3][3] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 316 | float G[3][3] = {0}; // state transition matrix |
tea5062001 | 0:c94b2f0a4409 | 317 | float GT[3][3] = {0}; // state transition matrix transport |
tea5062001 | 0:c94b2f0a4409 | 318 | float R[3][3] = { {0.000001 , 0 , 0} , {0 , 0.000001 , 0} , {0 , 0 , 0.000007} }; // process noise covariance matrix |
tea5062001 | 0:c94b2f0a4409 | 319 | |
tea5062001 | 0:c94b2f0a4409 | 320 | // encoder odometry |
tea5062001 | 0:c94b2f0a4409 | 321 | float th_enc = 0; |
tea5062001 | 0:c94b2f0a4409 | 322 | int th_enc_deg = 0; |
tea5062001 | 0:c94b2f0a4409 | 323 | float x_enc = 0; |
tea5062001 | 0:c94b2f0a4409 | 324 | float y_enc = 0; |
tea5062001 | 0:c94b2f0a4409 | 325 | |
tea5062001 | 0:c94b2f0a4409 | 326 | // global cross map variables |
tea5062001 | 0:c94b2f0a4409 | 327 | float block_length = 0.39; // m |
tea5062001 | 0:c94b2f0a4409 | 328 | float x_crom[4] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 329 | float y_crom[4] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 330 | |
tea5062001 | 0:c94b2f0a4409 | 331 | // update variables for cross detection |
tea5062001 | 0:c94b2f0a4409 | 332 | float Zcro[2][1] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 333 | float Zr[4] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 334 | int Za[4] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 335 | int Zphi[4] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 336 | int Zphi_deg_180[4] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 337 | float Zcro_hat[4][2][1] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 338 | float Zd[4][2][1] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 339 | float Pcro[4] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 340 | float Pcro_max = 0; |
tea5062001 | 0:c94b2f0a4409 | 341 | int i_Pcro_max = 0; |
tea5062001 | 0:c94b2f0a4409 | 342 | float e_r[4] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 343 | float mx_x[4] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 344 | float my_y[4] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 345 | float Zcro_hs[2][1] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 346 | float Hcro[4][2][3] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 347 | float Hcros[2][3] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 348 | float HcroT[4][3][2] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 349 | float HcroTs[3][2] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 350 | float Qcro[2][2] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 351 | float Scro[4][2][2] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 352 | float det_Scro[4] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 353 | float Scro_inv[4][2][2] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 354 | float Scro_is[2][2] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 355 | float Kcro[3][2] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 356 | |
tea5062001 | 0:c94b2f0a4409 | 357 | float Hcro_1[4][2][3] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 358 | float Hcro_2[4][2][2] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 359 | float Zcro_delta[2][1] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 360 | float Kcro_1[3][2] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 361 | float Kcro_2[3][1] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 362 | float Icro_1[3][3] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 363 | float Icro_2[3][3] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 364 | |
tea5062001 | 0:c94b2f0a4409 | 365 | // update variables for line detection |
tea5062001 | 0:c94b2f0a4409 | 366 | float Zli = 0; |
tea5062001 | 0:c94b2f0a4409 | 367 | float Zli_hat[4] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 368 | float Zli_diff[4] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 369 | float Zli_diff_min = 0; |
tea5062001 | 0:c94b2f0a4409 | 370 | int ind_diff_min = 0; |
tea5062001 | 0:c94b2f0a4409 | 371 | float Qli = 0.001; |
tea5062001 | 0:c94b2f0a4409 | 372 | float Sli = 0; |
tea5062001 | 0:c94b2f0a4409 | 373 | float Kli[3][1] = {0}; |
tea5062001 | 0:c94b2f0a4409 | 374 | |
tea5062001 | 0:c94b2f0a4409 | 375 | // update occasion |
tea5062001 | 0:c94b2f0a4409 | 376 | int camera_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 377 | int update_state = 0; |
tea5062001 | 0:c94b2f0a4409 | 378 | int singular_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 379 | int predict_count = 0; |
tea5062001 | 0:c94b2f0a4409 | 380 | int predict_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 381 | float up_dis = 0; |
tea5062001 | 0:c94b2f0a4409 | 382 | float up_rot = 0; |
tea5062001 | 0:c94b2f0a4409 | 383 | int up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 384 | float up_dis_r = 0.002; |
tea5062001 | 0:c94b2f0a4409 | 385 | float up_rot_r = PI/60; |
tea5062001 | 0:c94b2f0a4409 | 386 | |
tea5062001 | 0:c94b2f0a4409 | 387 | // encoder magnetometer gyro odometry |
tea5062001 | 0:c94b2f0a4409 | 388 | float th_emg = 0; |
tea5062001 | 0:c94b2f0a4409 | 389 | int th_emg_deg = 0; |
tea5062001 | 0:c94b2f0a4409 | 390 | float x_emg = 0; |
tea5062001 | 0:c94b2f0a4409 | 391 | float y_emg = 0; |
tea5062001 | 0:c94b2f0a4409 | 392 | |
tea5062001 | 0:c94b2f0a4409 | 393 | // select update source for debugging |
tea5062001 | 0:c94b2f0a4409 | 394 | // 0 for no update , 1 for cross update only , 2 for line update only , 3 for cross and line update together |
tea5062001 | 0:c94b2f0a4409 | 395 | int select_ups = 3; |
tea5062001 | 0:c94b2f0a4409 | 396 | |
tea5062001 | 0:c94b2f0a4409 | 397 | // select prediction model for debugging |
tea5062001 | 0:c94b2f0a4409 | 398 | // 0 for encoder magnetometer gyro fusion , 1 for encoder only |
tea5062001 | 0:c94b2f0a4409 | 399 | int select_pms = 1; |
tea5062001 | 0:c94b2f0a4409 | 400 | |
tea5062001 | 0:c94b2f0a4409 | 401 | // navigation |
tea5062001 | 0:c94b2f0a4409 | 402 | int mu_th_deg = 0; |
tea5062001 | 0:c94b2f0a4409 | 403 | int mu_th_deg_180 = 0; |
tea5062001 | 0:c94b2f0a4409 | 404 | float mu_th_PI = 0; |
tea5062001 | 0:c94b2f0a4409 | 405 | float Pxd = 0; |
tea5062001 | 0:c94b2f0a4409 | 406 | float Pyd = 0; |
tea5062001 | 0:c94b2f0a4409 | 407 | float Od = 0; |
tea5062001 | 0:c94b2f0a4409 | 408 | float delta_Pxd = 0; |
tea5062001 | 0:c94b2f0a4409 | 409 | float delta_Pyd = 0; |
tea5062001 | 0:c94b2f0a4409 | 410 | float delta_Od = 0; |
tea5062001 | 0:c94b2f0a4409 | 411 | float Kv = 0.55; |
tea5062001 | 0:c94b2f0a4409 | 412 | float Kw = 0.55; |
tea5062001 | 0:c94b2f0a4409 | 413 | float gain_v = 0; |
tea5062001 | 0:c94b2f0a4409 | 414 | float gain_w = 0; |
tea5062001 | 0:c94b2f0a4409 | 415 | float error_P = 0; |
tea5062001 | 0:c94b2f0a4409 | 416 | float error_O = 0; |
tea5062001 | 0:c94b2f0a4409 | 417 | int nav_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 418 | int nav_state = 1; |
tea5062001 | 0:c94b2f0a4409 | 419 | float distance_error_P = 0; |
tea5062001 | 0:c94b2f0a4409 | 420 | int line_tracker = 0; |
tea5062001 | 0:c94b2f0a4409 | 421 | |
tea5062001 | 0:c94b2f0a4409 | 422 | |
tea5062001 | 0:c94b2f0a4409 | 423 | int main() |
tea5062001 | 0:c94b2f0a4409 | 424 | { |
tea5062001 | 0:c94b2f0a4409 | 425 | t.start(); |
tea5062001 | 0:c94b2f0a4409 | 426 | |
tea5062001 | 0:c94b2f0a4409 | 427 | nh.initNode(); |
tea5062001 | 0:c94b2f0a4409 | 428 | |
tea5062001 | 0:c94b2f0a4409 | 429 | nh.subscribe(s); |
tea5062001 | 0:c94b2f0a4409 | 430 | nh.subscribe(s2); |
tea5062001 | 0:c94b2f0a4409 | 431 | nh.advertise(p); |
tea5062001 | 0:c94b2f0a4409 | 432 | |
tea5062001 | 0:c94b2f0a4409 | 433 | init_uart(); |
tea5062001 | 0:c94b2f0a4409 | 434 | |
tea5062001 | 0:c94b2f0a4409 | 435 | init_IMU(); |
tea5062001 | 0:c94b2f0a4409 | 436 | |
tea5062001 | 0:c94b2f0a4409 | 437 | myled = 1; |
tea5062001 | 0:c94b2f0a4409 | 438 | |
tea5062001 | 0:c94b2f0a4409 | 439 | while(1) |
tea5062001 | 0:c94b2f0a4409 | 440 | { |
tea5062001 | 0:c94b2f0a4409 | 441 | // receive labview data |
tea5062001 | 0:c94b2f0a4409 | 442 | if(uart_1.readable() > 0) |
tea5062001 | 0:c94b2f0a4409 | 443 | { |
tea5062001 | 0:c94b2f0a4409 | 444 | switch(uart_1.getc()) |
tea5062001 | 0:c94b2f0a4409 | 445 | { |
tea5062001 | 0:c94b2f0a4409 | 446 | case 'a': |
tea5062001 | 0:c94b2f0a4409 | 447 | check_flag = 1; |
tea5062001 | 0:c94b2f0a4409 | 448 | BK_ = 0; // light |
tea5062001 | 0:c94b2f0a4409 | 449 | break; |
tea5062001 | 0:c94b2f0a4409 | 450 | |
tea5062001 | 0:c94b2f0a4409 | 451 | case 's': |
tea5062001 | 0:c94b2f0a4409 | 452 | check_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 453 | BK_ = 1; // dark |
tea5062001 | 0:c94b2f0a4409 | 454 | break; |
tea5062001 | 0:c94b2f0a4409 | 455 | |
tea5062001 | 0:c94b2f0a4409 | 456 | case 'z': |
tea5062001 | 0:c94b2f0a4409 | 457 | phi_init_flag = 1; |
tea5062001 | 0:c94b2f0a4409 | 458 | B_ = 0; |
tea5062001 | 0:c94b2f0a4409 | 459 | break; |
tea5062001 | 0:c94b2f0a4409 | 460 | |
tea5062001 | 0:c94b2f0a4409 | 461 | case 'x': |
tea5062001 | 0:c94b2f0a4409 | 462 | phi_init_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 463 | B_ = 1; |
tea5062001 | 0:c94b2f0a4409 | 464 | break; |
tea5062001 | 0:c94b2f0a4409 | 465 | |
tea5062001 | 0:c94b2f0a4409 | 466 | case 'b': |
tea5062001 | 0:c94b2f0a4409 | 467 | bias_flag = 1; |
tea5062001 | 0:c94b2f0a4409 | 468 | break; |
tea5062001 | 0:c94b2f0a4409 | 469 | |
tea5062001 | 0:c94b2f0a4409 | 470 | case 'n': |
tea5062001 | 0:c94b2f0a4409 | 471 | bias_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 472 | break; |
tea5062001 | 0:c94b2f0a4409 | 473 | |
tea5062001 | 0:c94b2f0a4409 | 474 | case 'c': |
tea5062001 | 0:c94b2f0a4409 | 475 | camera_flag = 1; |
tea5062001 | 0:c94b2f0a4409 | 476 | break; |
tea5062001 | 0:c94b2f0a4409 | 477 | |
tea5062001 | 0:c94b2f0a4409 | 478 | case 'v': |
tea5062001 | 0:c94b2f0a4409 | 479 | camera_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 480 | break; |
tea5062001 | 0:c94b2f0a4409 | 481 | |
tea5062001 | 0:c94b2f0a4409 | 482 | case 'h': |
tea5062001 | 0:c94b2f0a4409 | 483 | select_ups = 0; |
tea5062001 | 0:c94b2f0a4409 | 484 | break; |
tea5062001 | 0:c94b2f0a4409 | 485 | |
tea5062001 | 0:c94b2f0a4409 | 486 | case 'j': |
tea5062001 | 0:c94b2f0a4409 | 487 | select_ups = 1; |
tea5062001 | 0:c94b2f0a4409 | 488 | break; |
tea5062001 | 0:c94b2f0a4409 | 489 | |
tea5062001 | 0:c94b2f0a4409 | 490 | case 'k': |
tea5062001 | 0:c94b2f0a4409 | 491 | select_ups = 2; |
tea5062001 | 0:c94b2f0a4409 | 492 | break; |
tea5062001 | 0:c94b2f0a4409 | 493 | |
tea5062001 | 0:c94b2f0a4409 | 494 | case 'l': |
tea5062001 | 0:c94b2f0a4409 | 495 | select_ups = 3; |
tea5062001 | 0:c94b2f0a4409 | 496 | break; |
tea5062001 | 0:c94b2f0a4409 | 497 | |
tea5062001 | 0:c94b2f0a4409 | 498 | case 'y': |
tea5062001 | 0:c94b2f0a4409 | 499 | nav_flag = 1; |
tea5062001 | 0:c94b2f0a4409 | 500 | break; |
tea5062001 | 0:c94b2f0a4409 | 501 | |
tea5062001 | 0:c94b2f0a4409 | 502 | case 'u': |
tea5062001 | 0:c94b2f0a4409 | 503 | nav_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 504 | break; |
tea5062001 | 0:c94b2f0a4409 | 505 | |
tea5062001 | 0:c94b2f0a4409 | 506 | default: |
tea5062001 | 0:c94b2f0a4409 | 507 | check_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 508 | phi_init_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 509 | fusion_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 510 | bias_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 511 | camera_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 512 | select_ups = 0; |
tea5062001 | 0:c94b2f0a4409 | 513 | nav_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 514 | break; |
tea5062001 | 0:c94b2f0a4409 | 515 | } |
tea5062001 | 0:c94b2f0a4409 | 516 | } |
tea5062001 | 0:c94b2f0a4409 | 517 | |
tea5062001 | 0:c94b2f0a4409 | 518 | // timer 1 : sensor fusion |
tea5062001 | 0:c94b2f0a4409 | 519 | if((t.read_us() - lastMilli) >= LOOPTIME) // 2000 us = 0.002 s |
tea5062001 | 0:c94b2f0a4409 | 520 | { |
tea5062001 | 0:c94b2f0a4409 | 521 | //myled = !myled; |
tea5062001 | 0:c94b2f0a4409 | 522 | |
tea5062001 | 0:c94b2f0a4409 | 523 | lastMilli = t.read_us(); |
tea5062001 | 0:c94b2f0a4409 | 524 | |
tea5062001 | 0:c94b2f0a4409 | 525 | // sensor initial start |
tea5062001 | 0:c94b2f0a4409 | 526 | if(sensor_flag == 0) |
tea5062001 | 0:c94b2f0a4409 | 527 | { |
tea5062001 | 0:c94b2f0a4409 | 528 | sensor_count++; |
tea5062001 | 0:c94b2f0a4409 | 529 | |
tea5062001 | 0:c94b2f0a4409 | 530 | if(sensor_count >= 100) |
tea5062001 | 0:c94b2f0a4409 | 531 | { |
tea5062001 | 0:c94b2f0a4409 | 532 | sensor_flag = 1; |
tea5062001 | 0:c94b2f0a4409 | 533 | sensor_count = 0; |
tea5062001 | 0:c94b2f0a4409 | 534 | } |
tea5062001 | 0:c94b2f0a4409 | 535 | } |
tea5062001 | 0:c94b2f0a4409 | 536 | else |
tea5062001 | 0:c94b2f0a4409 | 537 | { |
tea5062001 | 0:c94b2f0a4409 | 538 | read_sensor(); |
tea5062001 | 0:c94b2f0a4409 | 539 | |
tea5062001 | 0:c94b2f0a4409 | 540 | ////////////////// uart send data ////////////////////////////////////////////////////////////////////////////////////////////// |
tea5062001 | 0:c94b2f0a4409 | 541 | |
tea5062001 | 0:c94b2f0a4409 | 542 | display[0] = 1 * nav_flag; |
tea5062001 | 0:c94b2f0a4409 | 543 | display[1] = 1 * nav_state; |
tea5062001 | 0:c94b2f0a4409 | 544 | display[2] = 1 * up_check; |
tea5062001 | 0:c94b2f0a4409 | 545 | display[3] = 100 * error_P; |
tea5062001 | 0:c94b2f0a4409 | 546 | display[4] = 57.3 * error_O; |
tea5062001 | 0:c94b2f0a4409 | 547 | display[5] = 100 * distance_error_P; |
tea5062001 | 0:c94b2f0a4409 | 548 | display[6] = 100 * mu[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 549 | display[7] = 100 * mu[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 550 | display[8] = 57.3 * mu[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 551 | display[9] = 100 * x_enc; |
tea5062001 | 0:c94b2f0a4409 | 552 | display[10] = 100 * y_enc; |
tea5062001 | 0:c94b2f0a4409 | 553 | display[11] = 57.3 * th_enc; |
tea5062001 | 0:c94b2f0a4409 | 554 | |
tea5062001 | 0:c94b2f0a4409 | 555 | // display[0] = 1000 * Kcro_2[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 556 | // display[1] = 1000 * Kcro_2[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 557 | // display[2] = up_check; |
tea5062001 | 0:c94b2f0a4409 | 558 | // display[3] = 100 * Zcro[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 559 | // display[4] = 100 * Zcro_hat[i_Pcro_max][0][0]; |
tea5062001 | 0:c94b2f0a4409 | 560 | // display[5] = i_Pcro_max; |
tea5062001 | 0:c94b2f0a4409 | 561 | // display[6] = 57.3 * Zcro[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 562 | // display[7] = 57.3 * Zcro_hat[i_Pcro_max][1][0]; |
tea5062001 | 0:c94b2f0a4409 | 563 | // display[8] = Pcro_max; |
tea5062001 | 0:c94b2f0a4409 | 564 | // display[9] = 100 * mu[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 565 | // display[10] = 100 * mu[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 566 | // display[11] = 57.3 * mu[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 567 | |
tea5062001 | 0:c94b2f0a4409 | 568 | // display[0] = 100 * x_crom[0]; |
tea5062001 | 0:c94b2f0a4409 | 569 | // display[1] = 100 * y_crom[0]; |
tea5062001 | 0:c94b2f0a4409 | 570 | // display[2] = i_Pcro_max; |
tea5062001 | 0:c94b2f0a4409 | 571 | // display[3] = 100 * x_crom[1]; |
tea5062001 | 0:c94b2f0a4409 | 572 | // display[4] = 100 * y_crom[1]; |
tea5062001 | 0:c94b2f0a4409 | 573 | // display[5] = Pcro_max; |
tea5062001 | 0:c94b2f0a4409 | 574 | // display[6] = 100 * x_crom[2]; |
tea5062001 | 0:c94b2f0a4409 | 575 | // display[7] = 100 * y_crom[2]; |
tea5062001 | 0:c94b2f0a4409 | 576 | // display[8] = 100 * Xp; |
tea5062001 | 0:c94b2f0a4409 | 577 | // display[9] = 100 * x_crom[3]; |
tea5062001 | 0:c94b2f0a4409 | 578 | // display[10] = 100 * y_crom[3]; |
tea5062001 | 0:c94b2f0a4409 | 579 | // display[11] = 100 * Yp; |
tea5062001 | 0:c94b2f0a4409 | 580 | |
tea5062001 | 0:c94b2f0a4409 | 581 | // display[0] = 10000 * Magn_axis_zero[0]; |
tea5062001 | 0:c94b2f0a4409 | 582 | // display[1] = 10000 * Magn_axis_zero[1]; |
tea5062001 | 0:c94b2f0a4409 | 583 | // display[2] = 10000 * a; |
tea5062001 | 0:c94b2f0a4409 | 584 | // display[3] = 10000 * b; |
tea5062001 | 0:c94b2f0a4409 | 585 | // display[4] = 10000 * Magn_axis_zero2[0]; |
tea5062001 | 0:c94b2f0a4409 | 586 | // display[5] = 10000 * Magn_axis_zero2[1]; |
tea5062001 | 0:c94b2f0a4409 | 587 | // display[6] = 10000 * a2; |
tea5062001 | 0:c94b2f0a4409 | 588 | // display[7] = 10000 * b2; |
tea5062001 | 0:c94b2f0a4409 | 589 | // display[8] = 10000 * Be; |
tea5062001 | 0:c94b2f0a4409 | 590 | // display[9] = 100 * Xr; |
tea5062001 | 0:c94b2f0a4409 | 591 | // display[10] = 100 * Yr; |
tea5062001 | 0:c94b2f0a4409 | 592 | // display[11] = 57.3 * th_enc; |
tea5062001 | 0:c94b2f0a4409 | 593 | |
tea5062001 | 0:c94b2f0a4409 | 594 | // display[0] = 57.3 * phi_m_a; |
tea5062001 | 0:c94b2f0a4409 | 595 | // display[1] = 57.3 * phi_m2_a; |
tea5062001 | 0:c94b2f0a4409 | 596 | // display[2] = 57.3 * (0.5*phi_m_a + 0.5*phi_m2_a); |
tea5062001 | 0:c94b2f0a4409 | 597 | // display[3] = 57.3 * theta_fu; |
tea5062001 | 0:c94b2f0a4409 | 598 | // display[4] = 57.3 * theta_s; |
tea5062001 | 0:c94b2f0a4409 | 599 | // display[5] = 10000 * Q; |
tea5062001 | 0:c94b2f0a4409 | 600 | // display[6] = 57.3 * theta_me; |
tea5062001 | 0:c94b2f0a4409 | 601 | // display[7] = 57.3 * th_enc; |
tea5062001 | 0:c94b2f0a4409 | 602 | // display[8] = 57.3 * phi_m_a_avg; |
tea5062001 | 0:c94b2f0a4409 | 603 | // display[9] = 0; |
tea5062001 | 0:c94b2f0a4409 | 604 | // display[10] = 0; |
tea5062001 | 0:c94b2f0a4409 | 605 | // display[11] = 0; |
tea5062001 | 0:c94b2f0a4409 | 606 | |
tea5062001 | 0:c94b2f0a4409 | 607 | ////////////////// uart send data ////////////////////////////////////////////////////////////////////////////////////////////// |
tea5062001 | 0:c94b2f0a4409 | 608 | |
tea5062001 | 0:c94b2f0a4409 | 609 | uart_send(display); |
tea5062001 | 0:c94b2f0a4409 | 610 | } |
tea5062001 | 0:c94b2f0a4409 | 611 | } |
tea5062001 | 0:c94b2f0a4409 | 612 | |
tea5062001 | 0:c94b2f0a4409 | 613 | nh.spinOnce(); |
tea5062001 | 0:c94b2f0a4409 | 614 | |
tea5062001 | 0:c94b2f0a4409 | 615 | // timer 2 : publish cmd_vel for mag_cor |
tea5062001 | 0:c94b2f0a4409 | 616 | if((t.read_us() - lastMilli2) >= LOOPTIME2) // 100000 us = 0.1 s |
tea5062001 | 0:c94b2f0a4409 | 617 | { |
tea5062001 | 0:c94b2f0a4409 | 618 | lastMilli2 = t.read_us(); |
tea5062001 | 0:c94b2f0a4409 | 619 | |
tea5062001 | 0:c94b2f0a4409 | 620 | if(check_flag == 1) |
tea5062001 | 0:c94b2f0a4409 | 621 | { |
tea5062001 | 0:c94b2f0a4409 | 622 | vel_msg.angular.z = 0.35; |
tea5062001 | 0:c94b2f0a4409 | 623 | p.publish(&vel_msg); |
tea5062001 | 0:c94b2f0a4409 | 624 | } |
tea5062001 | 0:c94b2f0a4409 | 625 | } |
tea5062001 | 0:c94b2f0a4409 | 626 | |
tea5062001 | 0:c94b2f0a4409 | 627 | // timer 3 : take part of mag data |
tea5062001 | 0:c94b2f0a4409 | 628 | if((t.read_us() - lastMilli3) >= LOOPTIME3) // 300000 us = 0.3 s |
tea5062001 | 0:c94b2f0a4409 | 629 | { |
tea5062001 | 0:c94b2f0a4409 | 630 | lastMilli3 = t.read_us(); |
tea5062001 | 0:c94b2f0a4409 | 631 | |
tea5062001 | 0:c94b2f0a4409 | 632 | if(check_flag == 1) |
tea5062001 | 0:c94b2f0a4409 | 633 | { |
tea5062001 | 0:c94b2f0a4409 | 634 | if(th >= PI/12) // after magn data stable then take data |
tea5062001 | 0:c94b2f0a4409 | 635 | { |
tea5062001 | 0:c94b2f0a4409 | 636 | magx[ind] = Magn_axis_data_f[0]; |
tea5062001 | 0:c94b2f0a4409 | 637 | magy[ind] = Magn_axis_data_f[1]; |
tea5062001 | 0:c94b2f0a4409 | 638 | |
tea5062001 | 0:c94b2f0a4409 | 639 | magx2[ind] = Magn_axis_data_f2[0]; |
tea5062001 | 0:c94b2f0a4409 | 640 | magy2[ind] = Magn_axis_data_f2[1]; |
tea5062001 | 0:c94b2f0a4409 | 641 | |
tea5062001 | 0:c94b2f0a4409 | 642 | ind++; |
tea5062001 | 0:c94b2f0a4409 | 643 | if(ind >= 100) |
tea5062001 | 0:c94b2f0a4409 | 644 | ind = 0; |
tea5062001 | 0:c94b2f0a4409 | 645 | |
tea5062001 | 0:c94b2f0a4409 | 646 | ind_ = ind - 1; // send data index |
tea5062001 | 0:c94b2f0a4409 | 647 | } |
tea5062001 | 0:c94b2f0a4409 | 648 | } |
tea5062001 | 0:c94b2f0a4409 | 649 | } |
tea5062001 | 0:c94b2f0a4409 | 650 | |
tea5062001 | 0:c94b2f0a4409 | 651 | ////////// timer 5 : extended kalman filter //////////////////////////////////////////////////////////////////////////////////// |
tea5062001 | 0:c94b2f0a4409 | 652 | |
tea5062001 | 0:c94b2f0a4409 | 653 | if((t.read_us() - lastMilli5) >= LOOPTIME5) // 20000 us = 0.02 s |
tea5062001 | 0:c94b2f0a4409 | 654 | { |
tea5062001 | 0:c94b2f0a4409 | 655 | myled = !myled; |
tea5062001 | 0:c94b2f0a4409 | 656 | |
tea5062001 | 0:c94b2f0a4409 | 657 | lastMilli5 = t.read_us(); |
tea5062001 | 0:c94b2f0a4409 | 658 | |
tea5062001 | 0:c94b2f0a4409 | 659 | if(fusion_flag == 1) |
tea5062001 | 0:c94b2f0a4409 | 660 | { |
tea5062001 | 0:c94b2f0a4409 | 661 | // extended kalman filter for robot localization |
tea5062001 | 0:c94b2f0a4409 | 662 | |
tea5062001 | 0:c94b2f0a4409 | 663 | // *** Prediction Start *************************************************************** // |
tea5062001 | 0:c94b2f0a4409 | 664 | |
tea5062001 | 0:c94b2f0a4409 | 665 | // encoder odometry |
tea5062001 | 0:c94b2f0a4409 | 666 | th_enc = th_enc + omega_z*T2; |
tea5062001 | 0:c94b2f0a4409 | 667 | x_enc = x_enc + vel_x*cos(th_enc)*T2; |
tea5062001 | 0:c94b2f0a4409 | 668 | y_enc = y_enc + vel_x*sin(th_enc)*T2; |
tea5062001 | 0:c94b2f0a4409 | 669 | |
tea5062001 | 0:c94b2f0a4409 | 670 | // th_enc_deg range 0~359 deg |
tea5062001 | 0:c94b2f0a4409 | 671 | th_enc_deg = th_enc * 180/PI; |
tea5062001 | 0:c94b2f0a4409 | 672 | |
tea5062001 | 0:c94b2f0a4409 | 673 | if(th_enc_deg < 0) |
tea5062001 | 0:c94b2f0a4409 | 674 | th_enc_deg = th_enc_deg % 360 + 360; |
tea5062001 | 0:c94b2f0a4409 | 675 | else |
tea5062001 | 0:c94b2f0a4409 | 676 | th_enc_deg = th_enc_deg % 360; |
tea5062001 | 0:c94b2f0a4409 | 677 | |
tea5062001 | 0:c94b2f0a4409 | 678 | // encoder magnetometer gyro odometry |
tea5062001 | 0:c94b2f0a4409 | 679 | th_emg = theta_fu; |
tea5062001 | 0:c94b2f0a4409 | 680 | x_emg = x_emg + vel_x*cos(th_emg)*T2; |
tea5062001 | 0:c94b2f0a4409 | 681 | y_emg = y_emg + vel_x*sin(th_emg)*T2; |
tea5062001 | 0:c94b2f0a4409 | 682 | |
tea5062001 | 0:c94b2f0a4409 | 683 | // th_emg_deg range 0~359 deg |
tea5062001 | 0:c94b2f0a4409 | 684 | th_emg_deg = th_emg * 180/PI; |
tea5062001 | 0:c94b2f0a4409 | 685 | |
tea5062001 | 0:c94b2f0a4409 | 686 | if(th_emg_deg < 0) |
tea5062001 | 0:c94b2f0a4409 | 687 | th_emg_deg = th_emg_deg % 360 + 360; |
tea5062001 | 0:c94b2f0a4409 | 688 | else |
tea5062001 | 0:c94b2f0a4409 | 689 | th_emg_deg = th_emg_deg % 360; |
tea5062001 | 0:c94b2f0a4409 | 690 | |
tea5062001 | 0:c94b2f0a4409 | 691 | // update distance and rotation angle |
tea5062001 | 0:c94b2f0a4409 | 692 | up_dis = up_dis + T2*vel_x; |
tea5062001 | 0:c94b2f0a4409 | 693 | up_rot = up_rot + T2*omega_z; |
tea5062001 | 0:c94b2f0a4409 | 694 | |
tea5062001 | 0:c94b2f0a4409 | 695 | // mu_bar = g(u,mu) |
tea5062001 | 0:c94b2f0a4409 | 696 | switch(select_pms) |
tea5062001 | 0:c94b2f0a4409 | 697 | { |
tea5062001 | 0:c94b2f0a4409 | 698 | // 0 for encoder magnetometer gyro fusion |
tea5062001 | 0:c94b2f0a4409 | 699 | case 0: |
tea5062001 | 0:c94b2f0a4409 | 700 | mu_bar[0][0] = mu[0][0] + vel_x*cos(mu[2][0])*T2; |
tea5062001 | 0:c94b2f0a4409 | 701 | mu_bar[1][0] = mu[1][0] + vel_x*sin(mu[2][0])*T2; |
tea5062001 | 0:c94b2f0a4409 | 702 | mu_bar[2][0] = theta_fu; |
tea5062001 | 0:c94b2f0a4409 | 703 | |
tea5062001 | 0:c94b2f0a4409 | 704 | mu_bar_deg = theta_fu_deg; |
tea5062001 | 0:c94b2f0a4409 | 705 | break; |
tea5062001 | 0:c94b2f0a4409 | 706 | |
tea5062001 | 0:c94b2f0a4409 | 707 | // 1 for encoder only |
tea5062001 | 0:c94b2f0a4409 | 708 | case 1: |
tea5062001 | 0:c94b2f0a4409 | 709 | mu_bar[0][0] = mu[0][0] + vel_x*cos(mu[2][0])*T2; |
tea5062001 | 0:c94b2f0a4409 | 710 | mu_bar[1][0] = mu[1][0] + vel_x*sin(mu[2][0])*T2; |
tea5062001 | 0:c94b2f0a4409 | 711 | mu_bar[2][0] = mu[2][0] + omega_z*T2; |
tea5062001 | 0:c94b2f0a4409 | 712 | |
tea5062001 | 0:c94b2f0a4409 | 713 | // mu_bar_deg range 0~359 deg |
tea5062001 | 0:c94b2f0a4409 | 714 | mu_bar_deg = mu_bar[2][0] * 180/PI; |
tea5062001 | 0:c94b2f0a4409 | 715 | |
tea5062001 | 0:c94b2f0a4409 | 716 | if(mu_bar_deg < 0) |
tea5062001 | 0:c94b2f0a4409 | 717 | mu_bar_deg = mu_bar_deg % 360 + 360; |
tea5062001 | 0:c94b2f0a4409 | 718 | else |
tea5062001 | 0:c94b2f0a4409 | 719 | mu_bar_deg = mu_bar_deg % 360; |
tea5062001 | 0:c94b2f0a4409 | 720 | break; |
tea5062001 | 0:c94b2f0a4409 | 721 | } |
tea5062001 | 0:c94b2f0a4409 | 722 | |
tea5062001 | 0:c94b2f0a4409 | 723 | // covariance prediction accumulation timing |
tea5062001 | 0:c94b2f0a4409 | 724 | if(vel_x != 0 || omega_z != 0) |
tea5062001 | 0:c94b2f0a4409 | 725 | { |
tea5062001 | 0:c94b2f0a4409 | 726 | predict_count++; |
tea5062001 | 0:c94b2f0a4409 | 727 | } |
tea5062001 | 0:c94b2f0a4409 | 728 | |
tea5062001 | 0:c94b2f0a4409 | 729 | if(predict_count >= 25) |
tea5062001 | 0:c94b2f0a4409 | 730 | { |
tea5062001 | 0:c94b2f0a4409 | 731 | predict_flag = 1; |
tea5062001 | 0:c94b2f0a4409 | 732 | |
tea5062001 | 0:c94b2f0a4409 | 733 | predict_count = 0; |
tea5062001 | 0:c94b2f0a4409 | 734 | } |
tea5062001 | 0:c94b2f0a4409 | 735 | |
tea5062001 | 0:c94b2f0a4409 | 736 | if(predict_flag == 1) |
tea5062001 | 0:c94b2f0a4409 | 737 | { |
tea5062001 | 0:c94b2f0a4409 | 738 | // Sigma_bar = G*Sigma*G^T + R |
tea5062001 | 0:c94b2f0a4409 | 739 | G[0][0] = 1; |
tea5062001 | 0:c94b2f0a4409 | 740 | G[1][1] = 1; |
tea5062001 | 0:c94b2f0a4409 | 741 | G[2][2] = 1; |
tea5062001 | 0:c94b2f0a4409 | 742 | G[0][2] = -vel_x*sin(mu[2][0])*T2; |
tea5062001 | 0:c94b2f0a4409 | 743 | G[1][2] = vel_x*cos(mu[2][0])*T2; |
tea5062001 | 0:c94b2f0a4409 | 744 | |
tea5062001 | 0:c94b2f0a4409 | 745 | // get GT |
tea5062001 | 0:c94b2f0a4409 | 746 | GT[0][0] = 1; |
tea5062001 | 0:c94b2f0a4409 | 747 | GT[1][1] = 1; |
tea5062001 | 0:c94b2f0a4409 | 748 | GT[2][2] = 1; |
tea5062001 | 0:c94b2f0a4409 | 749 | GT[2][0] = G[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 750 | GT[2][1] = G[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 751 | |
tea5062001 | 0:c94b2f0a4409 | 752 | // G*Sigma = Sigma_mul_1 |
tea5062001 | 0:c94b2f0a4409 | 753 | Sigma_mul_1[0][0] = G[0][0]*Sigma[0][0] + G[0][1]*Sigma[1][0] + G[0][2]*Sigma[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 754 | Sigma_mul_1[0][1] = G[0][0]*Sigma[0][1] + G[0][1]*Sigma[1][1] + G[0][2]*Sigma[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 755 | Sigma_mul_1[0][2] = G[0][0]*Sigma[0][2] + G[0][1]*Sigma[1][2] + G[0][2]*Sigma[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 756 | Sigma_mul_1[1][0] = G[1][0]*Sigma[0][0] + G[1][1]*Sigma[1][0] + G[1][2]*Sigma[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 757 | Sigma_mul_1[1][1] = G[1][0]*Sigma[0][1] + G[1][1]*Sigma[1][1] + G[1][2]*Sigma[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 758 | Sigma_mul_1[1][2] = G[1][0]*Sigma[0][2] + G[1][1]*Sigma[1][2] + G[1][2]*Sigma[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 759 | Sigma_mul_1[2][0] = G[2][0]*Sigma[0][0] + G[2][1]*Sigma[1][0] + G[2][2]*Sigma[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 760 | Sigma_mul_1[2][1] = G[2][0]*Sigma[0][1] + G[2][1]*Sigma[1][1] + G[2][2]*Sigma[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 761 | Sigma_mul_1[2][2] = G[2][0]*Sigma[0][2] + G[2][1]*Sigma[1][2] + G[2][2]*Sigma[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 762 | |
tea5062001 | 0:c94b2f0a4409 | 763 | // G*Sigma * GT = Sigma_mul_1 * GT = Sigma_mul_2 |
tea5062001 | 0:c94b2f0a4409 | 764 | Sigma_mul_2[0][0] = Sigma_mul_1[0][0]*GT[0][0] + Sigma_mul_1[0][1]*GT[1][0] + Sigma_mul_1[0][2]*GT[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 765 | Sigma_mul_2[0][1] = Sigma_mul_1[0][0]*GT[0][1] + Sigma_mul_1[0][1]*GT[1][1] + Sigma_mul_1[0][2]*GT[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 766 | Sigma_mul_2[0][2] = Sigma_mul_1[0][0]*GT[0][2] + Sigma_mul_1[0][1]*GT[1][2] + Sigma_mul_1[0][2]*GT[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 767 | Sigma_mul_2[1][0] = Sigma_mul_1[1][0]*GT[0][0] + Sigma_mul_1[1][1]*GT[1][0] + Sigma_mul_1[1][2]*GT[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 768 | Sigma_mul_2[1][1] = Sigma_mul_1[1][0]*GT[0][1] + Sigma_mul_1[1][1]*GT[1][1] + Sigma_mul_1[1][2]*GT[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 769 | Sigma_mul_2[1][2] = Sigma_mul_1[1][0]*GT[0][2] + Sigma_mul_1[1][1]*GT[1][2] + Sigma_mul_1[1][2]*GT[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 770 | Sigma_mul_2[2][0] = Sigma_mul_1[2][0]*GT[0][0] + Sigma_mul_1[2][1]*GT[1][0] + Sigma_mul_1[2][2]*GT[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 771 | Sigma_mul_2[2][1] = Sigma_mul_1[2][0]*GT[0][1] + Sigma_mul_1[2][1]*GT[1][1] + Sigma_mul_1[2][2]*GT[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 772 | Sigma_mul_2[2][2] = Sigma_mul_1[2][0]*GT[0][2] + Sigma_mul_1[2][1]*GT[1][2] + Sigma_mul_1[2][2]*GT[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 773 | |
tea5062001 | 0:c94b2f0a4409 | 774 | // G*Sigma*GT + R = Sigma_mul_2 + R = Sigma_bar |
tea5062001 | 0:c94b2f0a4409 | 775 | Sigma_bar[0][0] = Sigma_mul_2[0][0] + R[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 776 | Sigma_bar[0][1] = Sigma_mul_2[0][1] + R[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 777 | Sigma_bar[0][2] = Sigma_mul_2[0][2] + R[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 778 | Sigma_bar[1][0] = Sigma_mul_2[1][0] + R[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 779 | Sigma_bar[1][1] = Sigma_mul_2[1][1] + R[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 780 | Sigma_bar[1][2] = Sigma_mul_2[1][2] + R[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 781 | Sigma_bar[2][0] = Sigma_mul_2[2][0] + R[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 782 | Sigma_bar[2][1] = Sigma_mul_2[2][1] + R[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 783 | Sigma_bar[2][2] = Sigma_mul_2[2][2] + R[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 784 | |
tea5062001 | 0:c94b2f0a4409 | 785 | predict_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 786 | } |
tea5062001 | 0:c94b2f0a4409 | 787 | |
tea5062001 | 0:c94b2f0a4409 | 788 | // *** Prediction End ***************************************************************** // |
tea5062001 | 0:c94b2f0a4409 | 789 | |
tea5062001 | 0:c94b2f0a4409 | 790 | // *** Update Start ******************************************************************* // |
tea5062001 | 0:c94b2f0a4409 | 791 | |
tea5062001 | 0:c94b2f0a4409 | 792 | if(vision_flag == 1 && camera_flag == 1) |
tea5062001 | 0:c94b2f0a4409 | 793 | { |
tea5062001 | 0:c94b2f0a4409 | 794 | if(update_source == 1 && singular_flag == 0) // cross detection |
tea5062001 | 0:c94b2f0a4409 | 795 | { |
tea5062001 | 0:c94b2f0a4409 | 796 | // global cross map |
tea5062001 | 0:c94b2f0a4409 | 797 | Xp = mu_bar[0][0] + cos(mu_bar[2][0])*Xr - sin(mu_bar[2][0])*Yr; |
tea5062001 | 0:c94b2f0a4409 | 798 | Yp = mu_bar[1][0] + sin(mu_bar[2][0])*Xr + cos(mu_bar[2][0])*Yr; |
tea5062001 | 0:c94b2f0a4409 | 799 | |
tea5062001 | 0:c94b2f0a4409 | 800 | if(Xp >= 0 && Yp >= 0) |
tea5062001 | 0:c94b2f0a4409 | 801 | { |
tea5062001 | 0:c94b2f0a4409 | 802 | // left down (0,0) |
tea5062001 | 0:c94b2f0a4409 | 803 | x_crom[0] = ((int)(Xp/block_length) + 0) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 804 | y_crom[0] = ((int)(Yp/block_length) + 0) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 805 | // right down (1,0) |
tea5062001 | 0:c94b2f0a4409 | 806 | x_crom[1] = ((int)(Xp/block_length) + 1) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 807 | y_crom[1] = ((int)(Yp/block_length) + 0) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 808 | // right up (1,1) |
tea5062001 | 0:c94b2f0a4409 | 809 | x_crom[2] = ((int)(Xp/block_length) + 1) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 810 | y_crom[2] = ((int)(Yp/block_length) + 1) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 811 | // left up (0,1) |
tea5062001 | 0:c94b2f0a4409 | 812 | x_crom[3] = ((int)(Xp/block_length) + 0) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 813 | y_crom[3] = ((int)(Yp/block_length) + 1) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 814 | } |
tea5062001 | 0:c94b2f0a4409 | 815 | else if(Xp < 0 && Yp >= 0) |
tea5062001 | 0:c94b2f0a4409 | 816 | { |
tea5062001 | 0:c94b2f0a4409 | 817 | // left down (-1,0) |
tea5062001 | 0:c94b2f0a4409 | 818 | x_crom[0] = ((int)(Xp/block_length) - 1) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 819 | y_crom[0] = ((int)(Yp/block_length) + 0) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 820 | // right down (0,0) |
tea5062001 | 0:c94b2f0a4409 | 821 | x_crom[1] = ((int)(Xp/block_length) + 0) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 822 | y_crom[1] = ((int)(Yp/block_length) + 0) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 823 | // right up (0,1) |
tea5062001 | 0:c94b2f0a4409 | 824 | x_crom[2] = ((int)(Xp/block_length) + 0) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 825 | y_crom[2] = ((int)(Yp/block_length) + 1) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 826 | // left up (-1,1) |
tea5062001 | 0:c94b2f0a4409 | 827 | x_crom[3] = ((int)(Xp/block_length) - 1) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 828 | y_crom[3] = ((int)(Yp/block_length) + 1) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 829 | } |
tea5062001 | 0:c94b2f0a4409 | 830 | else if(Xp < 0 && Yp < 0) |
tea5062001 | 0:c94b2f0a4409 | 831 | { |
tea5062001 | 0:c94b2f0a4409 | 832 | // left down (-1,-1) |
tea5062001 | 0:c94b2f0a4409 | 833 | x_crom[0] = ((int)(Xp/block_length) - 1) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 834 | y_crom[0] = ((int)(Yp/block_length) - 1) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 835 | // right down (0,-1) |
tea5062001 | 0:c94b2f0a4409 | 836 | x_crom[1] = ((int)(Xp/block_length) + 0) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 837 | y_crom[1] = ((int)(Yp/block_length) - 1) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 838 | // right up (0,0) |
tea5062001 | 0:c94b2f0a4409 | 839 | x_crom[2] = ((int)(Xp/block_length) + 0) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 840 | y_crom[2] = ((int)(Yp/block_length) + 0) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 841 | // left up (-1,0) |
tea5062001 | 0:c94b2f0a4409 | 842 | x_crom[3] = ((int)(Xp/block_length) - 1) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 843 | y_crom[3] = ((int)(Yp/block_length) + 0) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 844 | } |
tea5062001 | 0:c94b2f0a4409 | 845 | else if(Xp >= 0 && Yp < 0) |
tea5062001 | 0:c94b2f0a4409 | 846 | { |
tea5062001 | 0:c94b2f0a4409 | 847 | // left down (0,-1) |
tea5062001 | 0:c94b2f0a4409 | 848 | x_crom[0] = ((int)(Xp/block_length) + 0) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 849 | y_crom[0] = ((int)(Yp/block_length) - 1) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 850 | // right down (1,-1) |
tea5062001 | 0:c94b2f0a4409 | 851 | x_crom[1] = ((int)(Xp/block_length) + 1) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 852 | y_crom[1] = ((int)(Yp/block_length) - 1) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 853 | // right up (1,0) |
tea5062001 | 0:c94b2f0a4409 | 854 | x_crom[2] = ((int)(Xp/block_length) + 1) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 855 | y_crom[2] = ((int)(Yp/block_length) + 0) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 856 | // left up (0,0) |
tea5062001 | 0:c94b2f0a4409 | 857 | x_crom[3] = ((int)(Xp/block_length) + 0) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 858 | y_crom[3] = ((int)(Yp/block_length) + 0) * block_length; |
tea5062001 | 0:c94b2f0a4409 | 859 | } |
tea5062001 | 0:c94b2f0a4409 | 860 | |
tea5062001 | 0:c94b2f0a4409 | 861 | // cross relative distance measurement , polar coordinates : (Zcro[0][0] , Zcro[1][0]) |
tea5062001 | 0:c94b2f0a4409 | 862 | Zcro[0][0] = sqrt(pow(Xr,2) + pow(Yr,2)); |
tea5062001 | 0:c94b2f0a4409 | 863 | Zcro[1][0] = atan2(Yr,Xr); |
tea5062001 | 0:c94b2f0a4409 | 864 | |
tea5062001 | 0:c94b2f0a4409 | 865 | // cross relative distance prediction , polar coordinates : (Zr[i] , Zphi[i]) |
tea5062001 | 0:c94b2f0a4409 | 866 | for(int i = 0 ; i < 4 ; i++) |
tea5062001 | 0:c94b2f0a4409 | 867 | { |
tea5062001 | 0:c94b2f0a4409 | 868 | Zr[i] = sqrt(pow((x_crom[i] - mu_bar[0][0]),2) + pow((y_crom[i] - mu_bar[1][0]),2)); |
tea5062001 | 0:c94b2f0a4409 | 869 | |
tea5062001 | 0:c94b2f0a4409 | 870 | Za[i] = atan2((y_crom[i] - mu_bar[1][0]),(x_crom[i] - mu_bar[0][0])) * 180/PI; |
tea5062001 | 0:c94b2f0a4409 | 871 | |
tea5062001 | 0:c94b2f0a4409 | 872 | // Za[i] range 0~359 deg |
tea5062001 | 0:c94b2f0a4409 | 873 | if(Za[i] < 0) |
tea5062001 | 0:c94b2f0a4409 | 874 | Za[i] = Za[i] % 360 + 360; |
tea5062001 | 0:c94b2f0a4409 | 875 | else |
tea5062001 | 0:c94b2f0a4409 | 876 | Za[i] = Za[i] % 360; |
tea5062001 | 0:c94b2f0a4409 | 877 | |
tea5062001 | 0:c94b2f0a4409 | 878 | Zphi[i] = Za[i] - mu_bar_deg; |
tea5062001 | 0:c94b2f0a4409 | 879 | |
tea5062001 | 0:c94b2f0a4409 | 880 | // Zphi[i] range 0~359 deg |
tea5062001 | 0:c94b2f0a4409 | 881 | if(Zphi[i] < 0) |
tea5062001 | 0:c94b2f0a4409 | 882 | Zphi[i] = Zphi[i] % 360 + 360; |
tea5062001 | 0:c94b2f0a4409 | 883 | else |
tea5062001 | 0:c94b2f0a4409 | 884 | Zphi[i] = Zphi[i] % 360; |
tea5062001 | 0:c94b2f0a4409 | 885 | |
tea5062001 | 0:c94b2f0a4409 | 886 | // Zphi_deg_180[i] range -179~180 deg |
tea5062001 | 0:c94b2f0a4409 | 887 | if(Zphi[i] > 180) |
tea5062001 | 0:c94b2f0a4409 | 888 | Zphi_deg_180[i] = Zphi[i] - 360; |
tea5062001 | 0:c94b2f0a4409 | 889 | else |
tea5062001 | 0:c94b2f0a4409 | 890 | Zphi_deg_180[i] = Zphi[i]; |
tea5062001 | 0:c94b2f0a4409 | 891 | |
tea5062001 | 0:c94b2f0a4409 | 892 | Zcro_hat[i][0][0] = Zr[i]; |
tea5062001 | 0:c94b2f0a4409 | 893 | Zcro_hat[i][1][0] = Zphi_deg_180[i] * PI/180; |
tea5062001 | 0:c94b2f0a4409 | 894 | } |
tea5062001 | 0:c94b2f0a4409 | 895 | |
tea5062001 | 0:c94b2f0a4409 | 896 | // cross measurement likelihood |
tea5062001 | 0:c94b2f0a4409 | 897 | for(int i = 0 ; i < 4 ; i++) |
tea5062001 | 0:c94b2f0a4409 | 898 | { |
tea5062001 | 0:c94b2f0a4409 | 899 | // measurement transition matrix element |
tea5062001 | 0:c94b2f0a4409 | 900 | if(Zr[i] != 0) |
tea5062001 | 0:c94b2f0a4409 | 901 | { |
tea5062001 | 0:c94b2f0a4409 | 902 | e_r[i] = 1 / Zr[i]; |
tea5062001 | 0:c94b2f0a4409 | 903 | |
tea5062001 | 0:c94b2f0a4409 | 904 | singular_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 905 | } |
tea5062001 | 0:c94b2f0a4409 | 906 | else |
tea5062001 | 0:c94b2f0a4409 | 907 | { |
tea5062001 | 0:c94b2f0a4409 | 908 | singular_flag = 1; |
tea5062001 | 0:c94b2f0a4409 | 909 | } |
tea5062001 | 0:c94b2f0a4409 | 910 | |
tea5062001 | 0:c94b2f0a4409 | 911 | mx_x[i] = x_crom[i] - mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 912 | my_y[i] = y_crom[i] - mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 913 | |
tea5062001 | 0:c94b2f0a4409 | 914 | Hcro[i][0][0] = -mx_x[i] * e_r[i]; |
tea5062001 | 0:c94b2f0a4409 | 915 | Hcro[i][1][0] = my_y[i] * pow(e_r[i],2); |
tea5062001 | 0:c94b2f0a4409 | 916 | Hcro[i][0][1] = -my_y[i] * e_r[i]; |
tea5062001 | 0:c94b2f0a4409 | 917 | Hcro[i][1][1] = -mx_x[i] * pow(e_r[i],2); |
tea5062001 | 0:c94b2f0a4409 | 918 | Hcro[i][0][2] = 0; |
tea5062001 | 0:c94b2f0a4409 | 919 | Hcro[i][1][2] = -1; |
tea5062001 | 0:c94b2f0a4409 | 920 | |
tea5062001 | 0:c94b2f0a4409 | 921 | // get HcroT |
tea5062001 | 0:c94b2f0a4409 | 922 | HcroT[i][0][0] = Hcro[i][0][0]; |
tea5062001 | 0:c94b2f0a4409 | 923 | HcroT[i][1][0] = Hcro[i][0][1]; |
tea5062001 | 0:c94b2f0a4409 | 924 | HcroT[i][2][0] = Hcro[i][0][2]; |
tea5062001 | 0:c94b2f0a4409 | 925 | HcroT[i][0][1] = Hcro[i][1][0]; |
tea5062001 | 0:c94b2f0a4409 | 926 | HcroT[i][1][1] = Hcro[i][1][1]; |
tea5062001 | 0:c94b2f0a4409 | 927 | HcroT[i][2][1] = Hcro[i][1][2]; |
tea5062001 | 0:c94b2f0a4409 | 928 | |
tea5062001 | 0:c94b2f0a4409 | 929 | // H*Sigma_bar = Hcro_1 |
tea5062001 | 0:c94b2f0a4409 | 930 | Hcro_1[i][0][0] = Hcro[i][0][0]*Sigma_bar[0][0] + Hcro[i][0][1]*Sigma_bar[1][0] + Hcro[i][0][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 931 | Hcro_1[i][0][1] = Hcro[i][0][0]*Sigma_bar[0][1] + Hcro[i][0][1]*Sigma_bar[1][1] + Hcro[i][0][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 932 | Hcro_1[i][0][2] = Hcro[i][0][0]*Sigma_bar[0][2] + Hcro[i][0][1]*Sigma_bar[1][2] + Hcro[i][0][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 933 | Hcro_1[i][1][0] = Hcro[i][1][0]*Sigma_bar[0][0] + Hcro[i][1][1]*Sigma_bar[1][0] + Hcro[i][1][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 934 | Hcro_1[i][1][1] = Hcro[i][1][0]*Sigma_bar[0][1] + Hcro[i][1][1]*Sigma_bar[1][1] + Hcro[i][1][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 935 | Hcro_1[i][1][2] = Hcro[i][1][0]*Sigma_bar[0][2] + Hcro[i][1][1]*Sigma_bar[1][2] + Hcro[i][1][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 936 | |
tea5062001 | 0:c94b2f0a4409 | 937 | // H*Sigma_bar * HT = Hcro_1 * HT = Hcro_2 |
tea5062001 | 0:c94b2f0a4409 | 938 | Hcro_2[i][0][0] = Hcro_1[i][0][0]*HcroT[i][0][0] + Hcro_1[i][0][1]*HcroT[i][1][0] + Hcro_1[i][0][2]*HcroT[i][2][0]; |
tea5062001 | 0:c94b2f0a4409 | 939 | Hcro_2[i][0][1] = Hcro_1[i][0][0]*HcroT[i][0][1] + Hcro_1[i][0][1]*HcroT[i][1][1] + Hcro_1[i][0][2]*HcroT[i][2][1]; |
tea5062001 | 0:c94b2f0a4409 | 940 | Hcro_2[i][1][0] = Hcro_1[i][1][0]*HcroT[i][0][0] + Hcro_1[i][1][1]*HcroT[i][1][0] + Hcro_1[i][1][2]*HcroT[i][2][0]; |
tea5062001 | 0:c94b2f0a4409 | 941 | Hcro_2[i][1][1] = Hcro_1[i][1][0]*HcroT[i][0][1] + Hcro_1[i][1][1]*HcroT[i][1][1] + Hcro_1[i][1][2]*HcroT[i][2][1]; |
tea5062001 | 0:c94b2f0a4409 | 942 | |
tea5062001 | 0:c94b2f0a4409 | 943 | Qcro[0][0] = 0.0001; |
tea5062001 | 0:c94b2f0a4409 | 944 | Qcro[1][1] = 0.001; |
tea5062001 | 0:c94b2f0a4409 | 945 | |
tea5062001 | 0:c94b2f0a4409 | 946 | // H*Sigma_bar*HT + Q = Hcro_2 + Q = Scro |
tea5062001 | 0:c94b2f0a4409 | 947 | Scro[i][0][0] = Hcro_2[i][0][0] + Qcro[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 948 | Scro[i][0][1] = Hcro_2[i][0][1] + Qcro[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 949 | Scro[i][1][0] = Hcro_2[i][1][0] + Qcro[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 950 | Scro[i][1][1] = Hcro_2[i][1][1] + Qcro[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 951 | |
tea5062001 | 0:c94b2f0a4409 | 952 | det_Scro[i] = Scro[i][0][0]*Scro[i][1][1] - Scro[i][0][1]*Scro[i][1][0]; |
tea5062001 | 0:c94b2f0a4409 | 953 | |
tea5062001 | 0:c94b2f0a4409 | 954 | if(det_Scro[i] != 0) |
tea5062001 | 0:c94b2f0a4409 | 955 | { |
tea5062001 | 0:c94b2f0a4409 | 956 | Scro_inv[i][0][0] = Scro[i][1][1] / det_Scro[i]; |
tea5062001 | 0:c94b2f0a4409 | 957 | Scro_inv[i][0][1] = -Scro[i][0][1] / det_Scro[i]; |
tea5062001 | 0:c94b2f0a4409 | 958 | Scro_inv[i][1][0] = -Scro[i][1][0] / det_Scro[i]; |
tea5062001 | 0:c94b2f0a4409 | 959 | Scro_inv[i][1][1] = Scro[i][0][0] / det_Scro[i]; |
tea5062001 | 0:c94b2f0a4409 | 960 | |
tea5062001 | 0:c94b2f0a4409 | 961 | singular_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 962 | } |
tea5062001 | 0:c94b2f0a4409 | 963 | else |
tea5062001 | 0:c94b2f0a4409 | 964 | { |
tea5062001 | 0:c94b2f0a4409 | 965 | singular_flag = 1; |
tea5062001 | 0:c94b2f0a4409 | 966 | } |
tea5062001 | 0:c94b2f0a4409 | 967 | |
tea5062001 | 0:c94b2f0a4409 | 968 | // measurement difference |
tea5062001 | 0:c94b2f0a4409 | 969 | Zd[i][0][0] = Zcro[0][0] - Zcro_hat[i][0][0]; |
tea5062001 | 0:c94b2f0a4409 | 970 | Zd[i][1][0] = Zcro[1][0] - Zcro_hat[i][1][0]; |
tea5062001 | 0:c94b2f0a4409 | 971 | |
tea5062001 | 0:c94b2f0a4409 | 972 | // measurement likelihood |
tea5062001 | 0:c94b2f0a4409 | 973 | Pcro[i] = (1/sqrt(4*PI*PI*det_Scro[i]))*exp(-0.5*((Zd[i][0][0]*Scro_inv[i][0][0]+Zd[i][1][0]*Scro_inv[i][1][0])*Zd[i][0][0]+(Zd[i][0][0]*Scro[i][0][1]+Zd[i][1][0]*Scro_inv[i][1][1])*Zd[i][1][0])); |
tea5062001 | 0:c94b2f0a4409 | 974 | } |
tea5062001 | 0:c94b2f0a4409 | 975 | |
tea5062001 | 0:c94b2f0a4409 | 976 | // find the maximum likelihood and index |
tea5062001 | 0:c94b2f0a4409 | 977 | Pcro_max = Pcro[0]; |
tea5062001 | 0:c94b2f0a4409 | 978 | i_Pcro_max = 0; |
tea5062001 | 0:c94b2f0a4409 | 979 | |
tea5062001 | 0:c94b2f0a4409 | 980 | for(int j = 1 ; j < 4 ; j++) |
tea5062001 | 0:c94b2f0a4409 | 981 | { |
tea5062001 | 0:c94b2f0a4409 | 982 | if(Pcro[j] > Pcro_max) |
tea5062001 | 0:c94b2f0a4409 | 983 | { |
tea5062001 | 0:c94b2f0a4409 | 984 | Pcro_max = Pcro[j]; |
tea5062001 | 0:c94b2f0a4409 | 985 | i_Pcro_max = j; |
tea5062001 | 0:c94b2f0a4409 | 986 | } |
tea5062001 | 0:c94b2f0a4409 | 987 | } |
tea5062001 | 0:c94b2f0a4409 | 988 | |
tea5062001 | 0:c94b2f0a4409 | 989 | // Z_hat select |
tea5062001 | 0:c94b2f0a4409 | 990 | Zcro_hs[0][0] = Zcro_hat[i_Pcro_max][0][0]; |
tea5062001 | 0:c94b2f0a4409 | 991 | Zcro_hs[1][0] = Zcro_hat[i_Pcro_max][1][0]; |
tea5062001 | 0:c94b2f0a4409 | 992 | |
tea5062001 | 0:c94b2f0a4409 | 993 | // H select |
tea5062001 | 0:c94b2f0a4409 | 994 | Hcros[0][0] = Hcro[i_Pcro_max][0][0]; |
tea5062001 | 0:c94b2f0a4409 | 995 | Hcros[0][1] = Hcro[i_Pcro_max][0][1]; |
tea5062001 | 0:c94b2f0a4409 | 996 | Hcros[0][2] = Hcro[i_Pcro_max][0][2]; |
tea5062001 | 0:c94b2f0a4409 | 997 | Hcros[1][0] = Hcro[i_Pcro_max][1][0]; |
tea5062001 | 0:c94b2f0a4409 | 998 | Hcros[1][1] = Hcro[i_Pcro_max][1][1]; |
tea5062001 | 0:c94b2f0a4409 | 999 | Hcros[1][2] = Hcro[i_Pcro_max][1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1000 | |
tea5062001 | 0:c94b2f0a4409 | 1001 | // HT select |
tea5062001 | 0:c94b2f0a4409 | 1002 | HcroTs[0][0] = HcroT[i_Pcro_max][0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1003 | HcroTs[0][1] = HcroT[i_Pcro_max][0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1004 | HcroTs[1][0] = HcroT[i_Pcro_max][1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1005 | HcroTs[1][1] = HcroT[i_Pcro_max][1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1006 | HcroTs[2][0] = HcroT[i_Pcro_max][2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1007 | HcroTs[2][1] = HcroT[i_Pcro_max][2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1008 | |
tea5062001 | 0:c94b2f0a4409 | 1009 | // S^-1 select |
tea5062001 | 0:c94b2f0a4409 | 1010 | Scro_is[0][0] = Scro_inv[i_Pcro_max][0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1011 | Scro_is[0][1] = Scro_inv[i_Pcro_max][0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1012 | Scro_is[1][0] = Scro_inv[i_Pcro_max][1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1013 | Scro_is[1][1] = Scro_inv[i_Pcro_max][1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1014 | |
tea5062001 | 0:c94b2f0a4409 | 1015 | // get (Z-Z_hat) |
tea5062001 | 0:c94b2f0a4409 | 1016 | Zcro_delta[0][0] = Zcro[0][0] - Zcro_hs[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1017 | Zcro_delta[1][0] = Zcro[1][0] - Zcro_hs[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1018 | |
tea5062001 | 0:c94b2f0a4409 | 1019 | // Sigma_bar*HT = Kcro_1 |
tea5062001 | 0:c94b2f0a4409 | 1020 | Kcro_1[0][0] = Sigma_bar[0][0]*HcroTs[0][0] + Sigma_bar[0][1]*HcroTs[1][0] + Sigma_bar[0][2]*HcroTs[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1021 | Kcro_1[0][1] = Sigma_bar[0][0]*HcroTs[0][1] + Sigma_bar[0][1]*HcroTs[1][1] + Sigma_bar[0][2]*HcroTs[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1022 | Kcro_1[1][0] = Sigma_bar[1][0]*HcroTs[0][0] + Sigma_bar[1][1]*HcroTs[1][0] + Sigma_bar[1][2]*HcroTs[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1023 | Kcro_1[1][1] = Sigma_bar[1][0]*HcroTs[0][1] + Sigma_bar[1][1]*HcroTs[1][1] + Sigma_bar[1][2]*HcroTs[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1024 | Kcro_1[2][0] = Sigma_bar[2][0]*HcroTs[0][0] + Sigma_bar[2][1]*HcroTs[1][0] + Sigma_bar[2][2]*HcroTs[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1025 | Kcro_1[2][1] = Sigma_bar[2][0]*HcroTs[0][1] + Sigma_bar[2][1]*HcroTs[1][1] + Sigma_bar[2][2]*HcroTs[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1026 | |
tea5062001 | 0:c94b2f0a4409 | 1027 | // Sigma_bar*HT * S^-1 = Kcro_1 * S^-1 = Kcro |
tea5062001 | 0:c94b2f0a4409 | 1028 | Kcro[0][0] = Kcro_1[0][0]*Scro_is[0][0] + Kcro_1[0][1]*Scro_is[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1029 | Kcro[0][1] = Kcro_1[0][0]*Scro_is[0][1] + Kcro_1[0][1]*Scro_is[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1030 | Kcro[1][0] = Kcro_1[1][0]*Scro_is[0][0] + Kcro_1[1][1]*Scro_is[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1031 | Kcro[1][1] = Kcro_1[1][0]*Scro_is[0][1] + Kcro_1[1][1]*Scro_is[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1032 | Kcro[2][0] = Kcro_1[2][0]*Scro_is[0][0] + Kcro_1[2][1]*Scro_is[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1033 | Kcro[2][1] = Kcro_1[2][0]*Scro_is[0][1] + Kcro_1[2][1]*Scro_is[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1034 | |
tea5062001 | 0:c94b2f0a4409 | 1035 | // K*(Z-Z_hat) = Kcro_2 |
tea5062001 | 0:c94b2f0a4409 | 1036 | Kcro_2[0][0] = Kcro[0][0]*Zcro_delta[0][0] + Kcro[0][1]*Zcro_delta[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1037 | Kcro_2[1][0] = Kcro[1][0]*Zcro_delta[0][0] + Kcro[1][1]*Zcro_delta[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1038 | Kcro_2[2][0] = Kcro[2][0]*Zcro_delta[0][0] + Kcro[2][1]*Zcro_delta[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1039 | |
tea5062001 | 0:c94b2f0a4409 | 1040 | // K*H = Icro_1 |
tea5062001 | 0:c94b2f0a4409 | 1041 | Icro_1[0][0] = Kcro[0][0]*Hcros[0][0] + Kcro[0][1]*Hcros[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1042 | Icro_1[0][1] = Kcro[0][0]*Hcros[0][1] + Kcro[0][1]*Hcros[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1043 | Icro_1[0][2] = Kcro[0][0]*Hcros[0][2] + Kcro[0][1]*Hcros[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1044 | Icro_1[1][0] = Kcro[1][0]*Hcros[0][0] + Kcro[1][1]*Hcros[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1045 | Icro_1[1][1] = Kcro[1][0]*Hcros[0][1] + Kcro[1][1]*Hcros[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1046 | Icro_1[1][2] = Kcro[1][0]*Hcros[0][2] + Kcro[1][1]*Hcros[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1047 | Icro_1[2][0] = Kcro[2][0]*Hcros[0][0] + Kcro[2][1]*Hcros[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1048 | Icro_1[2][1] = Kcro[2][0]*Hcros[0][1] + Kcro[2][1]*Hcros[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1049 | Icro_1[2][2] = Kcro[2][0]*Hcros[0][2] + Kcro[2][1]*Hcros[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1050 | |
tea5062001 | 0:c94b2f0a4409 | 1051 | // (I - K*H) = (I - Icro_1) = Icro_2 |
tea5062001 | 0:c94b2f0a4409 | 1052 | Icro_2[0][0] = 1 - Icro_1[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1053 | Icro_2[0][1] = 0 - Icro_1[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1054 | Icro_2[0][2] = 0 - Icro_1[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1055 | Icro_2[1][0] = 0 - Icro_1[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1056 | Icro_2[1][1] = 1 - Icro_1[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1057 | Icro_2[1][2] = 0 - Icro_1[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1058 | Icro_2[2][0] = 0 - Icro_1[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1059 | Icro_2[2][1] = 0 - Icro_1[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1060 | Icro_2[2][2] = 1 - Icro_1[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1061 | |
tea5062001 | 0:c94b2f0a4409 | 1062 | update_state = 1; |
tea5062001 | 0:c94b2f0a4409 | 1063 | } |
tea5062001 | 0:c94b2f0a4409 | 1064 | // if(update_source == 1) end |
tea5062001 | 0:c94b2f0a4409 | 1065 | else if(update_source == 2) // line detection |
tea5062001 | 0:c94b2f0a4409 | 1066 | { |
tea5062001 | 0:c94b2f0a4409 | 1067 | // line angle measurement |
tea5062001 | 0:c94b2f0a4409 | 1068 | Zli = Theta_c; |
tea5062001 | 0:c94b2f0a4409 | 1069 | |
tea5062001 | 0:c94b2f0a4409 | 1070 | // measurement prediction covariance |
tea5062001 | 0:c94b2f0a4409 | 1071 | Sli = Sigma_bar[2][2] + Qli; |
tea5062001 | 0:c94b2f0a4409 | 1072 | |
tea5062001 | 0:c94b2f0a4409 | 1073 | // measurement likelihood (simplified method) |
tea5062001 | 0:c94b2f0a4409 | 1074 | Zli_hat[0] = mu_bar_deg - 90; |
tea5062001 | 0:c94b2f0a4409 | 1075 | Zli_hat[1] = mu_bar_deg - 180; |
tea5062001 | 0:c94b2f0a4409 | 1076 | Zli_hat[2] = mu_bar_deg - 270; |
tea5062001 | 0:c94b2f0a4409 | 1077 | Zli_hat[3] = mu_bar_deg - 360; |
tea5062001 | 0:c94b2f0a4409 | 1078 | if(Zli_hat[3] < -270) |
tea5062001 | 0:c94b2f0a4409 | 1079 | Zli_hat[3] = Zli_hat[3] + 360; |
tea5062001 | 0:c94b2f0a4409 | 1080 | |
tea5062001 | 0:c94b2f0a4409 | 1081 | // measurement difference square |
tea5062001 | 0:c94b2f0a4409 | 1082 | Zli_diff[0] = (Zli - Zli_hat[0]) * (Zli - Zli_hat[0]); |
tea5062001 | 0:c94b2f0a4409 | 1083 | Zli_diff[1] = (Zli - Zli_hat[1]) * (Zli - Zli_hat[1]); |
tea5062001 | 0:c94b2f0a4409 | 1084 | Zli_diff[2] = (Zli - Zli_hat[2]) * (Zli - Zli_hat[2]); |
tea5062001 | 0:c94b2f0a4409 | 1085 | Zli_diff[3] = (Zli - Zli_hat[3]) * (Zli - Zli_hat[3]); |
tea5062001 | 0:c94b2f0a4409 | 1086 | |
tea5062001 | 0:c94b2f0a4409 | 1087 | // find the minimum measurement difference square and index |
tea5062001 | 0:c94b2f0a4409 | 1088 | Zli_diff_min = Zli_diff[0]; |
tea5062001 | 0:c94b2f0a4409 | 1089 | ind_diff_min = 0; |
tea5062001 | 0:c94b2f0a4409 | 1090 | |
tea5062001 | 0:c94b2f0a4409 | 1091 | for(int j = 1 ; j < 4 ; j++) |
tea5062001 | 0:c94b2f0a4409 | 1092 | { |
tea5062001 | 0:c94b2f0a4409 | 1093 | if(Zli_diff[j] < Zli_diff_min) |
tea5062001 | 0:c94b2f0a4409 | 1094 | { |
tea5062001 | 0:c94b2f0a4409 | 1095 | Zli_diff_min = Zli_diff[j]; |
tea5062001 | 0:c94b2f0a4409 | 1096 | ind_diff_min = j; |
tea5062001 | 0:c94b2f0a4409 | 1097 | } |
tea5062001 | 0:c94b2f0a4409 | 1098 | } |
tea5062001 | 0:c94b2f0a4409 | 1099 | |
tea5062001 | 0:c94b2f0a4409 | 1100 | if(Zli_diff_min <= 150) |
tea5062001 | 0:c94b2f0a4409 | 1101 | { |
tea5062001 | 0:c94b2f0a4409 | 1102 | // Kli = Sigma_bar * HT * S^-1 |
tea5062001 | 0:c94b2f0a4409 | 1103 | Kli[2][0] = Sigma_bar[2][2] / Sli; |
tea5062001 | 0:c94b2f0a4409 | 1104 | |
tea5062001 | 0:c94b2f0a4409 | 1105 | update_state = 2; |
tea5062001 | 0:c94b2f0a4409 | 1106 | } |
tea5062001 | 0:c94b2f0a4409 | 1107 | else |
tea5062001 | 0:c94b2f0a4409 | 1108 | { |
tea5062001 | 0:c94b2f0a4409 | 1109 | update_state = 0; |
tea5062001 | 0:c94b2f0a4409 | 1110 | } |
tea5062001 | 0:c94b2f0a4409 | 1111 | } |
tea5062001 | 0:c94b2f0a4409 | 1112 | // else if(update_source == 2) end |
tea5062001 | 0:c94b2f0a4409 | 1113 | else |
tea5062001 | 0:c94b2f0a4409 | 1114 | { |
tea5062001 | 0:c94b2f0a4409 | 1115 | update_state = 0; |
tea5062001 | 0:c94b2f0a4409 | 1116 | } |
tea5062001 | 0:c94b2f0a4409 | 1117 | } |
tea5062001 | 0:c94b2f0a4409 | 1118 | |
tea5062001 | 0:c94b2f0a4409 | 1119 | // *** Update End ********************************************************************* // |
tea5062001 | 0:c94b2f0a4409 | 1120 | |
tea5062001 | 0:c94b2f0a4409 | 1121 | if(up_dis >= up_dis_r) |
tea5062001 | 0:c94b2f0a4409 | 1122 | { |
tea5062001 | 0:c94b2f0a4409 | 1123 | // update |
tea5062001 | 0:c94b2f0a4409 | 1124 | if(update_state == 1) |
tea5062001 | 0:c94b2f0a4409 | 1125 | { |
tea5062001 | 0:c94b2f0a4409 | 1126 | switch(select_ups) |
tea5062001 | 0:c94b2f0a4409 | 1127 | { |
tea5062001 | 0:c94b2f0a4409 | 1128 | // 0 for no update |
tea5062001 | 0:c94b2f0a4409 | 1129 | case 0: |
tea5062001 | 0:c94b2f0a4409 | 1130 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1131 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1132 | mu_bar[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1133 | |
tea5062001 | 0:c94b2f0a4409 | 1134 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1135 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1136 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1137 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1138 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1139 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1140 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1141 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1142 | Sigma_bar[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1143 | |
tea5062001 | 0:c94b2f0a4409 | 1144 | up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 1145 | break; |
tea5062001 | 0:c94b2f0a4409 | 1146 | |
tea5062001 | 0:c94b2f0a4409 | 1147 | // 1 for cross update only |
tea5062001 | 0:c94b2f0a4409 | 1148 | case 1: |
tea5062001 | 0:c94b2f0a4409 | 1149 | // mu_bar + K*(Z-Z_hat) = mu |
tea5062001 | 0:c94b2f0a4409 | 1150 | mu_bar[0][0] = mu_bar[0][0] + Kcro_2[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1151 | mu_bar[1][0] = mu_bar[1][0] + Kcro_2[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1152 | mu_bar[2][0] = mu_bar[2][0] + Kcro_2[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1153 | |
tea5062001 | 0:c94b2f0a4409 | 1154 | // (I - K*H) * Sigma_bar = Icro_2 * Sigma_bar = Sigma |
tea5062001 | 0:c94b2f0a4409 | 1155 | Sigma_bar[0][0] = Icro_2[0][0]*Sigma_bar[0][0] + Icro_2[0][1]*Sigma_bar[1][0] + Icro_2[0][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1156 | Sigma_bar[0][1] = Icro_2[0][0]*Sigma_bar[0][1] + Icro_2[0][1]*Sigma_bar[1][1] + Icro_2[0][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1157 | Sigma_bar[0][2] = Icro_2[0][0]*Sigma_bar[0][2] + Icro_2[0][1]*Sigma_bar[1][2] + Icro_2[0][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1158 | Sigma_bar[1][0] = Icro_2[1][0]*Sigma_bar[0][0] + Icro_2[1][1]*Sigma_bar[1][0] + Icro_2[1][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1159 | Sigma_bar[1][1] = Icro_2[1][0]*Sigma_bar[0][1] + Icro_2[1][1]*Sigma_bar[1][1] + Icro_2[1][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1160 | Sigma_bar[1][2] = Icro_2[1][0]*Sigma_bar[0][2] + Icro_2[1][1]*Sigma_bar[1][2] + Icro_2[1][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1161 | Sigma_bar[2][0] = Icro_2[2][0]*Sigma_bar[0][0] + Icro_2[2][1]*Sigma_bar[1][0] + Icro_2[2][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1162 | Sigma_bar[2][1] = Icro_2[2][0]*Sigma_bar[0][1] + Icro_2[2][1]*Sigma_bar[1][1] + Icro_2[2][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1163 | Sigma_bar[2][2] = Icro_2[2][0]*Sigma_bar[0][2] + Icro_2[2][1]*Sigma_bar[1][2] + Icro_2[2][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1164 | |
tea5062001 | 0:c94b2f0a4409 | 1165 | up_check = 1; |
tea5062001 | 0:c94b2f0a4409 | 1166 | break; |
tea5062001 | 0:c94b2f0a4409 | 1167 | |
tea5062001 | 0:c94b2f0a4409 | 1168 | // 2 for line update only |
tea5062001 | 0:c94b2f0a4409 | 1169 | case 2: |
tea5062001 | 0:c94b2f0a4409 | 1170 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1171 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1172 | mu_bar[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1173 | |
tea5062001 | 0:c94b2f0a4409 | 1174 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1175 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1176 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1177 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1178 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1179 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1180 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1181 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1182 | Sigma_bar[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1183 | |
tea5062001 | 0:c94b2f0a4409 | 1184 | up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 1185 | break; |
tea5062001 | 0:c94b2f0a4409 | 1186 | |
tea5062001 | 0:c94b2f0a4409 | 1187 | // 3 for cross and line update together |
tea5062001 | 0:c94b2f0a4409 | 1188 | case 3: |
tea5062001 | 0:c94b2f0a4409 | 1189 | // mu_bar + K*(Z-Z_hat) = mu |
tea5062001 | 0:c94b2f0a4409 | 1190 | mu_bar[0][0] = mu_bar[0][0] + Kcro_2[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1191 | mu_bar[1][0] = mu_bar[1][0] + Kcro_2[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1192 | mu_bar[2][0] = mu_bar[2][0] + Kcro_2[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1193 | |
tea5062001 | 0:c94b2f0a4409 | 1194 | // (I - K*H) * Sigma_bar = Icro_2 * Sigma_bar = Sigma |
tea5062001 | 0:c94b2f0a4409 | 1195 | Sigma_bar[0][0] = Icro_2[0][0]*Sigma_bar[0][0] + Icro_2[0][1]*Sigma_bar[1][0] + Icro_2[0][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1196 | Sigma_bar[0][1] = Icro_2[0][0]*Sigma_bar[0][1] + Icro_2[0][1]*Sigma_bar[1][1] + Icro_2[0][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1197 | Sigma_bar[0][2] = Icro_2[0][0]*Sigma_bar[0][2] + Icro_2[0][1]*Sigma_bar[1][2] + Icro_2[0][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1198 | Sigma_bar[1][0] = Icro_2[1][0]*Sigma_bar[0][0] + Icro_2[1][1]*Sigma_bar[1][0] + Icro_2[1][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1199 | Sigma_bar[1][1] = Icro_2[1][0]*Sigma_bar[0][1] + Icro_2[1][1]*Sigma_bar[1][1] + Icro_2[1][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1200 | Sigma_bar[1][2] = Icro_2[1][0]*Sigma_bar[0][2] + Icro_2[1][1]*Sigma_bar[1][2] + Icro_2[1][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1201 | Sigma_bar[2][0] = Icro_2[2][0]*Sigma_bar[0][0] + Icro_2[2][1]*Sigma_bar[1][0] + Icro_2[2][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1202 | Sigma_bar[2][1] = Icro_2[2][0]*Sigma_bar[0][1] + Icro_2[2][1]*Sigma_bar[1][1] + Icro_2[2][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1203 | Sigma_bar[2][2] = Icro_2[2][0]*Sigma_bar[0][2] + Icro_2[2][1]*Sigma_bar[1][2] + Icro_2[2][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1204 | |
tea5062001 | 0:c94b2f0a4409 | 1205 | up_check = 1; |
tea5062001 | 0:c94b2f0a4409 | 1206 | break; |
tea5062001 | 0:c94b2f0a4409 | 1207 | } |
tea5062001 | 0:c94b2f0a4409 | 1208 | } |
tea5062001 | 0:c94b2f0a4409 | 1209 | else if(update_state == 2) |
tea5062001 | 0:c94b2f0a4409 | 1210 | { |
tea5062001 | 0:c94b2f0a4409 | 1211 | switch(select_ups) |
tea5062001 | 0:c94b2f0a4409 | 1212 | { |
tea5062001 | 0:c94b2f0a4409 | 1213 | // 0 for no update |
tea5062001 | 0:c94b2f0a4409 | 1214 | case 0: |
tea5062001 | 0:c94b2f0a4409 | 1215 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1216 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1217 | mu_bar[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1218 | |
tea5062001 | 0:c94b2f0a4409 | 1219 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1220 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1221 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1222 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1223 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1224 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1225 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1226 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1227 | Sigma_bar[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1228 | |
tea5062001 | 0:c94b2f0a4409 | 1229 | up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 1230 | break; |
tea5062001 | 0:c94b2f0a4409 | 1231 | |
tea5062001 | 0:c94b2f0a4409 | 1232 | // 1 for cross update only |
tea5062001 | 0:c94b2f0a4409 | 1233 | case 1: |
tea5062001 | 0:c94b2f0a4409 | 1234 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1235 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1236 | mu_bar[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1237 | |
tea5062001 | 0:c94b2f0a4409 | 1238 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1239 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1240 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1241 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1242 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1243 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1244 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1245 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1246 | Sigma_bar[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1247 | |
tea5062001 | 0:c94b2f0a4409 | 1248 | up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 1249 | break; |
tea5062001 | 0:c94b2f0a4409 | 1250 | |
tea5062001 | 0:c94b2f0a4409 | 1251 | // 2 for line update only |
tea5062001 | 0:c94b2f0a4409 | 1252 | case 2: |
tea5062001 | 0:c94b2f0a4409 | 1253 | // mu = mu_bar + K*(Z-Z_hat) |
tea5062001 | 0:c94b2f0a4409 | 1254 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1255 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1256 | mu_bar[2][0] = mu_bar[2][0] + Kli[2][0]*(Zli - Zli_hat[ind_diff_min])*PI/180; |
tea5062001 | 0:c94b2f0a4409 | 1257 | |
tea5062001 | 0:c94b2f0a4409 | 1258 | // Sigma = (I - K*H) * Sigma_bar |
tea5062001 | 0:c94b2f0a4409 | 1259 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1260 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1261 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1262 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1263 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1264 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1265 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1266 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1267 | Sigma_bar[2][2] = Sigma_bar[2][2] - Kli[2][0]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1268 | |
tea5062001 | 0:c94b2f0a4409 | 1269 | up_check = 2; |
tea5062001 | 0:c94b2f0a4409 | 1270 | break; |
tea5062001 | 0:c94b2f0a4409 | 1271 | |
tea5062001 | 0:c94b2f0a4409 | 1272 | // 3 for cross and line update together |
tea5062001 | 0:c94b2f0a4409 | 1273 | case 3: |
tea5062001 | 0:c94b2f0a4409 | 1274 | // mu = mu_bar + K*(Z-Z_hat) |
tea5062001 | 0:c94b2f0a4409 | 1275 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1276 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1277 | mu_bar[2][0] = mu_bar[2][0] + Kli[2][0]*(Zli - Zli_hat[ind_diff_min])*PI/180; |
tea5062001 | 0:c94b2f0a4409 | 1278 | |
tea5062001 | 0:c94b2f0a4409 | 1279 | // Sigma = (I - K*H) * Sigma_bar |
tea5062001 | 0:c94b2f0a4409 | 1280 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1281 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1282 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1283 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1284 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1285 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1286 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1287 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1288 | Sigma_bar[2][2] = Sigma_bar[2][2] - Kli[2][0]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1289 | |
tea5062001 | 0:c94b2f0a4409 | 1290 | up_check = 2; |
tea5062001 | 0:c94b2f0a4409 | 1291 | break; |
tea5062001 | 0:c94b2f0a4409 | 1292 | } |
tea5062001 | 0:c94b2f0a4409 | 1293 | } |
tea5062001 | 0:c94b2f0a4409 | 1294 | else |
tea5062001 | 0:c94b2f0a4409 | 1295 | { |
tea5062001 | 0:c94b2f0a4409 | 1296 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1297 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1298 | mu_bar[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1299 | |
tea5062001 | 0:c94b2f0a4409 | 1300 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1301 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1302 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1303 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1304 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1305 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1306 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1307 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1308 | Sigma_bar[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1309 | |
tea5062001 | 0:c94b2f0a4409 | 1310 | up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 1311 | } |
tea5062001 | 0:c94b2f0a4409 | 1312 | |
tea5062001 | 0:c94b2f0a4409 | 1313 | up_dis = 0; |
tea5062001 | 0:c94b2f0a4409 | 1314 | } |
tea5062001 | 0:c94b2f0a4409 | 1315 | else if(up_dis <= -up_dis_r) |
tea5062001 | 0:c94b2f0a4409 | 1316 | { |
tea5062001 | 0:c94b2f0a4409 | 1317 | // update |
tea5062001 | 0:c94b2f0a4409 | 1318 | if(update_state == 1) |
tea5062001 | 0:c94b2f0a4409 | 1319 | { |
tea5062001 | 0:c94b2f0a4409 | 1320 | switch(select_ups) |
tea5062001 | 0:c94b2f0a4409 | 1321 | { |
tea5062001 | 0:c94b2f0a4409 | 1322 | // 0 for no update |
tea5062001 | 0:c94b2f0a4409 | 1323 | case 0: |
tea5062001 | 0:c94b2f0a4409 | 1324 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1325 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1326 | mu_bar[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1327 | |
tea5062001 | 0:c94b2f0a4409 | 1328 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1329 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1330 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1331 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1332 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1333 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1334 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1335 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1336 | Sigma_bar[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1337 | |
tea5062001 | 0:c94b2f0a4409 | 1338 | up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 1339 | break; |
tea5062001 | 0:c94b2f0a4409 | 1340 | |
tea5062001 | 0:c94b2f0a4409 | 1341 | // 1 for cross update only |
tea5062001 | 0:c94b2f0a4409 | 1342 | case 1: |
tea5062001 | 0:c94b2f0a4409 | 1343 | // mu_bar + K*(Z-Z_hat) = mu |
tea5062001 | 0:c94b2f0a4409 | 1344 | mu_bar[0][0] = mu_bar[0][0] + Kcro_2[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1345 | mu_bar[1][0] = mu_bar[1][0] + Kcro_2[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1346 | mu_bar[2][0] = mu_bar[2][0] + Kcro_2[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1347 | |
tea5062001 | 0:c94b2f0a4409 | 1348 | // (I - K*H) * Sigma_bar = Icro_2 * Sigma_bar = Sigma |
tea5062001 | 0:c94b2f0a4409 | 1349 | Sigma_bar[0][0] = Icro_2[0][0]*Sigma_bar[0][0] + Icro_2[0][1]*Sigma_bar[1][0] + Icro_2[0][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1350 | Sigma_bar[0][1] = Icro_2[0][0]*Sigma_bar[0][1] + Icro_2[0][1]*Sigma_bar[1][1] + Icro_2[0][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1351 | Sigma_bar[0][2] = Icro_2[0][0]*Sigma_bar[0][2] + Icro_2[0][1]*Sigma_bar[1][2] + Icro_2[0][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1352 | Sigma_bar[1][0] = Icro_2[1][0]*Sigma_bar[0][0] + Icro_2[1][1]*Sigma_bar[1][0] + Icro_2[1][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1353 | Sigma_bar[1][1] = Icro_2[1][0]*Sigma_bar[0][1] + Icro_2[1][1]*Sigma_bar[1][1] + Icro_2[1][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1354 | Sigma_bar[1][2] = Icro_2[1][0]*Sigma_bar[0][2] + Icro_2[1][1]*Sigma_bar[1][2] + Icro_2[1][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1355 | Sigma_bar[2][0] = Icro_2[2][0]*Sigma_bar[0][0] + Icro_2[2][1]*Sigma_bar[1][0] + Icro_2[2][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1356 | Sigma_bar[2][1] = Icro_2[2][0]*Sigma_bar[0][1] + Icro_2[2][1]*Sigma_bar[1][1] + Icro_2[2][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1357 | Sigma_bar[2][2] = Icro_2[2][0]*Sigma_bar[0][2] + Icro_2[2][1]*Sigma_bar[1][2] + Icro_2[2][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1358 | |
tea5062001 | 0:c94b2f0a4409 | 1359 | up_check = 1; |
tea5062001 | 0:c94b2f0a4409 | 1360 | break; |
tea5062001 | 0:c94b2f0a4409 | 1361 | |
tea5062001 | 0:c94b2f0a4409 | 1362 | // 2 for line update only |
tea5062001 | 0:c94b2f0a4409 | 1363 | case 2: |
tea5062001 | 0:c94b2f0a4409 | 1364 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1365 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1366 | mu_bar[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1367 | |
tea5062001 | 0:c94b2f0a4409 | 1368 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1369 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1370 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1371 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1372 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1373 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1374 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1375 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1376 | Sigma_bar[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1377 | |
tea5062001 | 0:c94b2f0a4409 | 1378 | up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 1379 | break; |
tea5062001 | 0:c94b2f0a4409 | 1380 | |
tea5062001 | 0:c94b2f0a4409 | 1381 | // 3 for cross and line update together |
tea5062001 | 0:c94b2f0a4409 | 1382 | case 3: |
tea5062001 | 0:c94b2f0a4409 | 1383 | // mu_bar + K*(Z-Z_hat) = mu |
tea5062001 | 0:c94b2f0a4409 | 1384 | mu_bar[0][0] = mu_bar[0][0] + Kcro_2[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1385 | mu_bar[1][0] = mu_bar[1][0] + Kcro_2[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1386 | mu_bar[2][0] = mu_bar[2][0] + Kcro_2[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1387 | |
tea5062001 | 0:c94b2f0a4409 | 1388 | // (I - K*H) * Sigma_bar = Icro_2 * Sigma_bar = Sigma |
tea5062001 | 0:c94b2f0a4409 | 1389 | Sigma_bar[0][0] = Icro_2[0][0]*Sigma_bar[0][0] + Icro_2[0][1]*Sigma_bar[1][0] + Icro_2[0][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1390 | Sigma_bar[0][1] = Icro_2[0][0]*Sigma_bar[0][1] + Icro_2[0][1]*Sigma_bar[1][1] + Icro_2[0][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1391 | Sigma_bar[0][2] = Icro_2[0][0]*Sigma_bar[0][2] + Icro_2[0][1]*Sigma_bar[1][2] + Icro_2[0][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1392 | Sigma_bar[1][0] = Icro_2[1][0]*Sigma_bar[0][0] + Icro_2[1][1]*Sigma_bar[1][0] + Icro_2[1][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1393 | Sigma_bar[1][1] = Icro_2[1][0]*Sigma_bar[0][1] + Icro_2[1][1]*Sigma_bar[1][1] + Icro_2[1][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1394 | Sigma_bar[1][2] = Icro_2[1][0]*Sigma_bar[0][2] + Icro_2[1][1]*Sigma_bar[1][2] + Icro_2[1][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1395 | Sigma_bar[2][0] = Icro_2[2][0]*Sigma_bar[0][0] + Icro_2[2][1]*Sigma_bar[1][0] + Icro_2[2][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1396 | Sigma_bar[2][1] = Icro_2[2][0]*Sigma_bar[0][1] + Icro_2[2][1]*Sigma_bar[1][1] + Icro_2[2][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1397 | Sigma_bar[2][2] = Icro_2[2][0]*Sigma_bar[0][2] + Icro_2[2][1]*Sigma_bar[1][2] + Icro_2[2][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1398 | |
tea5062001 | 0:c94b2f0a4409 | 1399 | up_check = 1; |
tea5062001 | 0:c94b2f0a4409 | 1400 | break; |
tea5062001 | 0:c94b2f0a4409 | 1401 | } |
tea5062001 | 0:c94b2f0a4409 | 1402 | } |
tea5062001 | 0:c94b2f0a4409 | 1403 | else if(update_state == 2) |
tea5062001 | 0:c94b2f0a4409 | 1404 | { |
tea5062001 | 0:c94b2f0a4409 | 1405 | switch(select_ups) |
tea5062001 | 0:c94b2f0a4409 | 1406 | { |
tea5062001 | 0:c94b2f0a4409 | 1407 | // 0 for no update |
tea5062001 | 0:c94b2f0a4409 | 1408 | case 0: |
tea5062001 | 0:c94b2f0a4409 | 1409 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1410 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1411 | mu_bar[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1412 | |
tea5062001 | 0:c94b2f0a4409 | 1413 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1414 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1415 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1416 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1417 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1418 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1419 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1420 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1421 | Sigma_bar[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1422 | |
tea5062001 | 0:c94b2f0a4409 | 1423 | up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 1424 | break; |
tea5062001 | 0:c94b2f0a4409 | 1425 | |
tea5062001 | 0:c94b2f0a4409 | 1426 | // 1 for cross update only |
tea5062001 | 0:c94b2f0a4409 | 1427 | case 1: |
tea5062001 | 0:c94b2f0a4409 | 1428 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1429 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1430 | mu_bar[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1431 | |
tea5062001 | 0:c94b2f0a4409 | 1432 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1433 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1434 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1435 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1436 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1437 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1438 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1439 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1440 | Sigma_bar[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1441 | |
tea5062001 | 0:c94b2f0a4409 | 1442 | up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 1443 | break; |
tea5062001 | 0:c94b2f0a4409 | 1444 | |
tea5062001 | 0:c94b2f0a4409 | 1445 | // 2 for line update only |
tea5062001 | 0:c94b2f0a4409 | 1446 | case 2: |
tea5062001 | 0:c94b2f0a4409 | 1447 | // mu = mu_bar + K*(Z-Z_hat) |
tea5062001 | 0:c94b2f0a4409 | 1448 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1449 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1450 | mu_bar[2][0] = mu_bar[2][0] + Kli[2][0]*(Zli - Zli_hat[ind_diff_min])*PI/180; |
tea5062001 | 0:c94b2f0a4409 | 1451 | |
tea5062001 | 0:c94b2f0a4409 | 1452 | // Sigma = (I - K*H) * Sigma_bar |
tea5062001 | 0:c94b2f0a4409 | 1453 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1454 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1455 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1456 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1457 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1458 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1459 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1460 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1461 | Sigma_bar[2][2] = Sigma_bar[2][2] - Kli[2][0]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1462 | |
tea5062001 | 0:c94b2f0a4409 | 1463 | up_check = 2; |
tea5062001 | 0:c94b2f0a4409 | 1464 | break; |
tea5062001 | 0:c94b2f0a4409 | 1465 | |
tea5062001 | 0:c94b2f0a4409 | 1466 | // 3 for cross and line update together |
tea5062001 | 0:c94b2f0a4409 | 1467 | case 3: |
tea5062001 | 0:c94b2f0a4409 | 1468 | // mu = mu_bar + K*(Z-Z_hat) |
tea5062001 | 0:c94b2f0a4409 | 1469 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1470 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1471 | mu_bar[2][0] = mu_bar[2][0] + Kli[2][0]*(Zli - Zli_hat[ind_diff_min])*PI/180; |
tea5062001 | 0:c94b2f0a4409 | 1472 | |
tea5062001 | 0:c94b2f0a4409 | 1473 | // Sigma = (I - K*H) * Sigma_bar |
tea5062001 | 0:c94b2f0a4409 | 1474 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1475 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1476 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1477 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1478 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1479 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1480 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1481 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1482 | Sigma_bar[2][2] = Sigma_bar[2][2] - Kli[2][0]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1483 | |
tea5062001 | 0:c94b2f0a4409 | 1484 | up_check = 2; |
tea5062001 | 0:c94b2f0a4409 | 1485 | break; |
tea5062001 | 0:c94b2f0a4409 | 1486 | } |
tea5062001 | 0:c94b2f0a4409 | 1487 | } |
tea5062001 | 0:c94b2f0a4409 | 1488 | else |
tea5062001 | 0:c94b2f0a4409 | 1489 | { |
tea5062001 | 0:c94b2f0a4409 | 1490 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1491 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1492 | mu_bar[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1493 | |
tea5062001 | 0:c94b2f0a4409 | 1494 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1495 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1496 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1497 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1498 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1499 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1500 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1501 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1502 | Sigma_bar[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1503 | |
tea5062001 | 0:c94b2f0a4409 | 1504 | up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 1505 | } |
tea5062001 | 0:c94b2f0a4409 | 1506 | |
tea5062001 | 0:c94b2f0a4409 | 1507 | up_dis = 0; |
tea5062001 | 0:c94b2f0a4409 | 1508 | } |
tea5062001 | 0:c94b2f0a4409 | 1509 | else if(up_rot >= up_rot_r) |
tea5062001 | 0:c94b2f0a4409 | 1510 | { |
tea5062001 | 0:c94b2f0a4409 | 1511 | // update |
tea5062001 | 0:c94b2f0a4409 | 1512 | if(update_state == 1) |
tea5062001 | 0:c94b2f0a4409 | 1513 | { |
tea5062001 | 0:c94b2f0a4409 | 1514 | switch(select_ups) |
tea5062001 | 0:c94b2f0a4409 | 1515 | { |
tea5062001 | 0:c94b2f0a4409 | 1516 | // 0 for no update |
tea5062001 | 0:c94b2f0a4409 | 1517 | case 0: |
tea5062001 | 0:c94b2f0a4409 | 1518 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1519 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1520 | mu_bar[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1521 | |
tea5062001 | 0:c94b2f0a4409 | 1522 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1523 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1524 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1525 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1526 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1527 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1528 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1529 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1530 | Sigma_bar[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1531 | |
tea5062001 | 0:c94b2f0a4409 | 1532 | up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 1533 | break; |
tea5062001 | 0:c94b2f0a4409 | 1534 | |
tea5062001 | 0:c94b2f0a4409 | 1535 | // 1 for cross update only |
tea5062001 | 0:c94b2f0a4409 | 1536 | case 1: |
tea5062001 | 0:c94b2f0a4409 | 1537 | // mu_bar + K*(Z-Z_hat) = mu |
tea5062001 | 0:c94b2f0a4409 | 1538 | mu_bar[0][0] = mu_bar[0][0] + Kcro_2[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1539 | mu_bar[1][0] = mu_bar[1][0] + Kcro_2[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1540 | mu_bar[2][0] = mu_bar[2][0] + Kcro_2[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1541 | |
tea5062001 | 0:c94b2f0a4409 | 1542 | // (I - K*H) * Sigma_bar = Icro_2 * Sigma_bar = Sigma |
tea5062001 | 0:c94b2f0a4409 | 1543 | Sigma_bar[0][0] = Icro_2[0][0]*Sigma_bar[0][0] + Icro_2[0][1]*Sigma_bar[1][0] + Icro_2[0][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1544 | Sigma_bar[0][1] = Icro_2[0][0]*Sigma_bar[0][1] + Icro_2[0][1]*Sigma_bar[1][1] + Icro_2[0][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1545 | Sigma_bar[0][2] = Icro_2[0][0]*Sigma_bar[0][2] + Icro_2[0][1]*Sigma_bar[1][2] + Icro_2[0][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1546 | Sigma_bar[1][0] = Icro_2[1][0]*Sigma_bar[0][0] + Icro_2[1][1]*Sigma_bar[1][0] + Icro_2[1][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1547 | Sigma_bar[1][1] = Icro_2[1][0]*Sigma_bar[0][1] + Icro_2[1][1]*Sigma_bar[1][1] + Icro_2[1][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1548 | Sigma_bar[1][2] = Icro_2[1][0]*Sigma_bar[0][2] + Icro_2[1][1]*Sigma_bar[1][2] + Icro_2[1][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1549 | Sigma_bar[2][0] = Icro_2[2][0]*Sigma_bar[0][0] + Icro_2[2][1]*Sigma_bar[1][0] + Icro_2[2][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1550 | Sigma_bar[2][1] = Icro_2[2][0]*Sigma_bar[0][1] + Icro_2[2][1]*Sigma_bar[1][1] + Icro_2[2][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1551 | Sigma_bar[2][2] = Icro_2[2][0]*Sigma_bar[0][2] + Icro_2[2][1]*Sigma_bar[1][2] + Icro_2[2][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1552 | |
tea5062001 | 0:c94b2f0a4409 | 1553 | up_check = 1; |
tea5062001 | 0:c94b2f0a4409 | 1554 | break; |
tea5062001 | 0:c94b2f0a4409 | 1555 | |
tea5062001 | 0:c94b2f0a4409 | 1556 | // 2 for line update only |
tea5062001 | 0:c94b2f0a4409 | 1557 | case 2: |
tea5062001 | 0:c94b2f0a4409 | 1558 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1559 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1560 | mu_bar[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1561 | |
tea5062001 | 0:c94b2f0a4409 | 1562 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1563 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1564 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1565 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1566 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1567 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1568 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1569 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1570 | Sigma_bar[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1571 | |
tea5062001 | 0:c94b2f0a4409 | 1572 | up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 1573 | break; |
tea5062001 | 0:c94b2f0a4409 | 1574 | |
tea5062001 | 0:c94b2f0a4409 | 1575 | // 3 for cross and line update together |
tea5062001 | 0:c94b2f0a4409 | 1576 | case 3: |
tea5062001 | 0:c94b2f0a4409 | 1577 | // mu_bar + K*(Z-Z_hat) = mu |
tea5062001 | 0:c94b2f0a4409 | 1578 | mu_bar[0][0] = mu_bar[0][0] + Kcro_2[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1579 | mu_bar[1][0] = mu_bar[1][0] + Kcro_2[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1580 | mu_bar[2][0] = mu_bar[2][0] + Kcro_2[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1581 | |
tea5062001 | 0:c94b2f0a4409 | 1582 | // (I - K*H) * Sigma_bar = Icro_2 * Sigma_bar = Sigma |
tea5062001 | 0:c94b2f0a4409 | 1583 | Sigma_bar[0][0] = Icro_2[0][0]*Sigma_bar[0][0] + Icro_2[0][1]*Sigma_bar[1][0] + Icro_2[0][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1584 | Sigma_bar[0][1] = Icro_2[0][0]*Sigma_bar[0][1] + Icro_2[0][1]*Sigma_bar[1][1] + Icro_2[0][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1585 | Sigma_bar[0][2] = Icro_2[0][0]*Sigma_bar[0][2] + Icro_2[0][1]*Sigma_bar[1][2] + Icro_2[0][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1586 | Sigma_bar[1][0] = Icro_2[1][0]*Sigma_bar[0][0] + Icro_2[1][1]*Sigma_bar[1][0] + Icro_2[1][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1587 | Sigma_bar[1][1] = Icro_2[1][0]*Sigma_bar[0][1] + Icro_2[1][1]*Sigma_bar[1][1] + Icro_2[1][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1588 | Sigma_bar[1][2] = Icro_2[1][0]*Sigma_bar[0][2] + Icro_2[1][1]*Sigma_bar[1][2] + Icro_2[1][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1589 | Sigma_bar[2][0] = Icro_2[2][0]*Sigma_bar[0][0] + Icro_2[2][1]*Sigma_bar[1][0] + Icro_2[2][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1590 | Sigma_bar[2][1] = Icro_2[2][0]*Sigma_bar[0][1] + Icro_2[2][1]*Sigma_bar[1][1] + Icro_2[2][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1591 | Sigma_bar[2][2] = Icro_2[2][0]*Sigma_bar[0][2] + Icro_2[2][1]*Sigma_bar[1][2] + Icro_2[2][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1592 | |
tea5062001 | 0:c94b2f0a4409 | 1593 | up_check = 1; |
tea5062001 | 0:c94b2f0a4409 | 1594 | break; |
tea5062001 | 0:c94b2f0a4409 | 1595 | } |
tea5062001 | 0:c94b2f0a4409 | 1596 | } |
tea5062001 | 0:c94b2f0a4409 | 1597 | else if(update_state == 2) |
tea5062001 | 0:c94b2f0a4409 | 1598 | { |
tea5062001 | 0:c94b2f0a4409 | 1599 | switch(select_ups) |
tea5062001 | 0:c94b2f0a4409 | 1600 | { |
tea5062001 | 0:c94b2f0a4409 | 1601 | // 0 for no update |
tea5062001 | 0:c94b2f0a4409 | 1602 | case 0: |
tea5062001 | 0:c94b2f0a4409 | 1603 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1604 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1605 | mu_bar[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1606 | |
tea5062001 | 0:c94b2f0a4409 | 1607 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1608 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1609 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1610 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1611 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1612 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1613 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1614 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1615 | Sigma_bar[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1616 | |
tea5062001 | 0:c94b2f0a4409 | 1617 | up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 1618 | break; |
tea5062001 | 0:c94b2f0a4409 | 1619 | |
tea5062001 | 0:c94b2f0a4409 | 1620 | // 1 for cross update only |
tea5062001 | 0:c94b2f0a4409 | 1621 | case 1: |
tea5062001 | 0:c94b2f0a4409 | 1622 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1623 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1624 | mu_bar[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1625 | |
tea5062001 | 0:c94b2f0a4409 | 1626 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1627 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1628 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1629 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1630 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1631 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1632 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1633 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1634 | Sigma_bar[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1635 | |
tea5062001 | 0:c94b2f0a4409 | 1636 | up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 1637 | break; |
tea5062001 | 0:c94b2f0a4409 | 1638 | |
tea5062001 | 0:c94b2f0a4409 | 1639 | // 2 for line update only |
tea5062001 | 0:c94b2f0a4409 | 1640 | case 2: |
tea5062001 | 0:c94b2f0a4409 | 1641 | // mu = mu_bar + K*(Z-Z_hat) |
tea5062001 | 0:c94b2f0a4409 | 1642 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1643 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1644 | mu_bar[2][0] = mu_bar[2][0] + Kli[2][0]*(Zli - Zli_hat[ind_diff_min])*PI/180; |
tea5062001 | 0:c94b2f0a4409 | 1645 | |
tea5062001 | 0:c94b2f0a4409 | 1646 | // Sigma = (I - K*H) * Sigma_bar |
tea5062001 | 0:c94b2f0a4409 | 1647 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1648 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1649 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1650 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1651 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1652 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1653 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1654 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1655 | Sigma_bar[2][2] = Sigma_bar[2][2] - Kli[2][0]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1656 | |
tea5062001 | 0:c94b2f0a4409 | 1657 | up_check = 2; |
tea5062001 | 0:c94b2f0a4409 | 1658 | break; |
tea5062001 | 0:c94b2f0a4409 | 1659 | |
tea5062001 | 0:c94b2f0a4409 | 1660 | // 3 for cross and line update together |
tea5062001 | 0:c94b2f0a4409 | 1661 | case 3: |
tea5062001 | 0:c94b2f0a4409 | 1662 | // mu = mu_bar + K*(Z-Z_hat) |
tea5062001 | 0:c94b2f0a4409 | 1663 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1664 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1665 | mu_bar[2][0] = mu_bar[2][0] + Kli[2][0]*(Zli - Zli_hat[ind_diff_min])*PI/180; |
tea5062001 | 0:c94b2f0a4409 | 1666 | |
tea5062001 | 0:c94b2f0a4409 | 1667 | // Sigma = (I - K*H) * Sigma_bar |
tea5062001 | 0:c94b2f0a4409 | 1668 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1669 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1670 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1671 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1672 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1673 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1674 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1675 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1676 | Sigma_bar[2][2] = Sigma_bar[2][2] - Kli[2][0]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1677 | |
tea5062001 | 0:c94b2f0a4409 | 1678 | up_check = 2; |
tea5062001 | 0:c94b2f0a4409 | 1679 | break; |
tea5062001 | 0:c94b2f0a4409 | 1680 | } |
tea5062001 | 0:c94b2f0a4409 | 1681 | } |
tea5062001 | 0:c94b2f0a4409 | 1682 | else |
tea5062001 | 0:c94b2f0a4409 | 1683 | { |
tea5062001 | 0:c94b2f0a4409 | 1684 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1685 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1686 | mu_bar[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1687 | |
tea5062001 | 0:c94b2f0a4409 | 1688 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1689 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1690 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1691 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1692 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1693 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1694 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1695 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1696 | Sigma_bar[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1697 | |
tea5062001 | 0:c94b2f0a4409 | 1698 | up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 1699 | } |
tea5062001 | 0:c94b2f0a4409 | 1700 | |
tea5062001 | 0:c94b2f0a4409 | 1701 | up_rot = 0; |
tea5062001 | 0:c94b2f0a4409 | 1702 | } |
tea5062001 | 0:c94b2f0a4409 | 1703 | else if(up_rot <= -up_rot_r) |
tea5062001 | 0:c94b2f0a4409 | 1704 | { |
tea5062001 | 0:c94b2f0a4409 | 1705 | // update |
tea5062001 | 0:c94b2f0a4409 | 1706 | if(update_state == 1) |
tea5062001 | 0:c94b2f0a4409 | 1707 | { |
tea5062001 | 0:c94b2f0a4409 | 1708 | switch(select_ups) |
tea5062001 | 0:c94b2f0a4409 | 1709 | { |
tea5062001 | 0:c94b2f0a4409 | 1710 | // 0 for no update |
tea5062001 | 0:c94b2f0a4409 | 1711 | case 0: |
tea5062001 | 0:c94b2f0a4409 | 1712 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1713 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1714 | mu_bar[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1715 | |
tea5062001 | 0:c94b2f0a4409 | 1716 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1717 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1718 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1719 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1720 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1721 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1722 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1723 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1724 | Sigma_bar[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1725 | |
tea5062001 | 0:c94b2f0a4409 | 1726 | up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 1727 | break; |
tea5062001 | 0:c94b2f0a4409 | 1728 | |
tea5062001 | 0:c94b2f0a4409 | 1729 | // 1 for cross update only |
tea5062001 | 0:c94b2f0a4409 | 1730 | case 1: |
tea5062001 | 0:c94b2f0a4409 | 1731 | // mu_bar + K*(Z-Z_hat) = mu |
tea5062001 | 0:c94b2f0a4409 | 1732 | mu_bar[0][0] = mu_bar[0][0] + Kcro_2[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1733 | mu_bar[1][0] = mu_bar[1][0] + Kcro_2[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1734 | mu_bar[2][0] = mu_bar[2][0] + Kcro_2[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1735 | |
tea5062001 | 0:c94b2f0a4409 | 1736 | // (I - K*H) * Sigma_bar = Icro_2 * Sigma_bar = Sigma |
tea5062001 | 0:c94b2f0a4409 | 1737 | Sigma_bar[0][0] = Icro_2[0][0]*Sigma_bar[0][0] + Icro_2[0][1]*Sigma_bar[1][0] + Icro_2[0][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1738 | Sigma_bar[0][1] = Icro_2[0][0]*Sigma_bar[0][1] + Icro_2[0][1]*Sigma_bar[1][1] + Icro_2[0][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1739 | Sigma_bar[0][2] = Icro_2[0][0]*Sigma_bar[0][2] + Icro_2[0][1]*Sigma_bar[1][2] + Icro_2[0][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1740 | Sigma_bar[1][0] = Icro_2[1][0]*Sigma_bar[0][0] + Icro_2[1][1]*Sigma_bar[1][0] + Icro_2[1][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1741 | Sigma_bar[1][1] = Icro_2[1][0]*Sigma_bar[0][1] + Icro_2[1][1]*Sigma_bar[1][1] + Icro_2[1][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1742 | Sigma_bar[1][2] = Icro_2[1][0]*Sigma_bar[0][2] + Icro_2[1][1]*Sigma_bar[1][2] + Icro_2[1][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1743 | Sigma_bar[2][0] = Icro_2[2][0]*Sigma_bar[0][0] + Icro_2[2][1]*Sigma_bar[1][0] + Icro_2[2][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1744 | Sigma_bar[2][1] = Icro_2[2][0]*Sigma_bar[0][1] + Icro_2[2][1]*Sigma_bar[1][1] + Icro_2[2][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1745 | Sigma_bar[2][2] = Icro_2[2][0]*Sigma_bar[0][2] + Icro_2[2][1]*Sigma_bar[1][2] + Icro_2[2][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1746 | |
tea5062001 | 0:c94b2f0a4409 | 1747 | up_check = 1; |
tea5062001 | 0:c94b2f0a4409 | 1748 | break; |
tea5062001 | 0:c94b2f0a4409 | 1749 | |
tea5062001 | 0:c94b2f0a4409 | 1750 | // 2 for line update only |
tea5062001 | 0:c94b2f0a4409 | 1751 | case 2: |
tea5062001 | 0:c94b2f0a4409 | 1752 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1753 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1754 | mu_bar[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1755 | |
tea5062001 | 0:c94b2f0a4409 | 1756 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1757 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1758 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1759 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1760 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1761 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1762 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1763 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1764 | Sigma_bar[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1765 | |
tea5062001 | 0:c94b2f0a4409 | 1766 | up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 1767 | break; |
tea5062001 | 0:c94b2f0a4409 | 1768 | |
tea5062001 | 0:c94b2f0a4409 | 1769 | // 3 for cross and line update together |
tea5062001 | 0:c94b2f0a4409 | 1770 | case 3: |
tea5062001 | 0:c94b2f0a4409 | 1771 | // mu_bar + K*(Z-Z_hat) = mu |
tea5062001 | 0:c94b2f0a4409 | 1772 | mu_bar[0][0] = mu_bar[0][0] + Kcro_2[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1773 | mu_bar[1][0] = mu_bar[1][0] + Kcro_2[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1774 | mu_bar[2][0] = mu_bar[2][0] + Kcro_2[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1775 | |
tea5062001 | 0:c94b2f0a4409 | 1776 | // (I - K*H) * Sigma_bar = Icro_2 * Sigma_bar = Sigma |
tea5062001 | 0:c94b2f0a4409 | 1777 | Sigma_bar[0][0] = Icro_2[0][0]*Sigma_bar[0][0] + Icro_2[0][1]*Sigma_bar[1][0] + Icro_2[0][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1778 | Sigma_bar[0][1] = Icro_2[0][0]*Sigma_bar[0][1] + Icro_2[0][1]*Sigma_bar[1][1] + Icro_2[0][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1779 | Sigma_bar[0][2] = Icro_2[0][0]*Sigma_bar[0][2] + Icro_2[0][1]*Sigma_bar[1][2] + Icro_2[0][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1780 | Sigma_bar[1][0] = Icro_2[1][0]*Sigma_bar[0][0] + Icro_2[1][1]*Sigma_bar[1][0] + Icro_2[1][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1781 | Sigma_bar[1][1] = Icro_2[1][0]*Sigma_bar[0][1] + Icro_2[1][1]*Sigma_bar[1][1] + Icro_2[1][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1782 | Sigma_bar[1][2] = Icro_2[1][0]*Sigma_bar[0][2] + Icro_2[1][1]*Sigma_bar[1][2] + Icro_2[1][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1783 | Sigma_bar[2][0] = Icro_2[2][0]*Sigma_bar[0][0] + Icro_2[2][1]*Sigma_bar[1][0] + Icro_2[2][2]*Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1784 | Sigma_bar[2][1] = Icro_2[2][0]*Sigma_bar[0][1] + Icro_2[2][1]*Sigma_bar[1][1] + Icro_2[2][2]*Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1785 | Sigma_bar[2][2] = Icro_2[2][0]*Sigma_bar[0][2] + Icro_2[2][1]*Sigma_bar[1][2] + Icro_2[2][2]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1786 | |
tea5062001 | 0:c94b2f0a4409 | 1787 | up_check = 1; |
tea5062001 | 0:c94b2f0a4409 | 1788 | break; |
tea5062001 | 0:c94b2f0a4409 | 1789 | } |
tea5062001 | 0:c94b2f0a4409 | 1790 | } |
tea5062001 | 0:c94b2f0a4409 | 1791 | else if(update_state == 2) |
tea5062001 | 0:c94b2f0a4409 | 1792 | { |
tea5062001 | 0:c94b2f0a4409 | 1793 | switch(select_ups) |
tea5062001 | 0:c94b2f0a4409 | 1794 | { |
tea5062001 | 0:c94b2f0a4409 | 1795 | // 0 for no update |
tea5062001 | 0:c94b2f0a4409 | 1796 | case 0: |
tea5062001 | 0:c94b2f0a4409 | 1797 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1798 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1799 | mu_bar[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1800 | |
tea5062001 | 0:c94b2f0a4409 | 1801 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1802 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1803 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1804 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1805 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1806 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1807 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1808 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1809 | Sigma_bar[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1810 | |
tea5062001 | 0:c94b2f0a4409 | 1811 | up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 1812 | break; |
tea5062001 | 0:c94b2f0a4409 | 1813 | |
tea5062001 | 0:c94b2f0a4409 | 1814 | // 1 for cross update only |
tea5062001 | 0:c94b2f0a4409 | 1815 | case 1: |
tea5062001 | 0:c94b2f0a4409 | 1816 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1817 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1818 | mu_bar[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1819 | |
tea5062001 | 0:c94b2f0a4409 | 1820 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1821 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1822 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1823 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1824 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1825 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1826 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1827 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1828 | Sigma_bar[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1829 | |
tea5062001 | 0:c94b2f0a4409 | 1830 | up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 1831 | break; |
tea5062001 | 0:c94b2f0a4409 | 1832 | |
tea5062001 | 0:c94b2f0a4409 | 1833 | // 2 for line update only |
tea5062001 | 0:c94b2f0a4409 | 1834 | case 2: |
tea5062001 | 0:c94b2f0a4409 | 1835 | // mu = mu_bar + K*(Z-Z_hat) |
tea5062001 | 0:c94b2f0a4409 | 1836 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1837 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1838 | mu_bar[2][0] = mu_bar[2][0] + Kli[2][0]*(Zli - Zli_hat[ind_diff_min])*PI/180; |
tea5062001 | 0:c94b2f0a4409 | 1839 | |
tea5062001 | 0:c94b2f0a4409 | 1840 | // Sigma = (I - K*H) * Sigma_bar |
tea5062001 | 0:c94b2f0a4409 | 1841 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1842 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1843 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1844 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1845 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1846 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1847 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1848 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1849 | Sigma_bar[2][2] = Sigma_bar[2][2] - Kli[2][0]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1850 | |
tea5062001 | 0:c94b2f0a4409 | 1851 | up_check = 2; |
tea5062001 | 0:c94b2f0a4409 | 1852 | break; |
tea5062001 | 0:c94b2f0a4409 | 1853 | |
tea5062001 | 0:c94b2f0a4409 | 1854 | // 3 for cross and line update together |
tea5062001 | 0:c94b2f0a4409 | 1855 | case 3: |
tea5062001 | 0:c94b2f0a4409 | 1856 | // mu = mu_bar + K*(Z-Z_hat) |
tea5062001 | 0:c94b2f0a4409 | 1857 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1858 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1859 | mu_bar[2][0] = mu_bar[2][0] + Kli[2][0]*(Zli - Zli_hat[ind_diff_min])*PI/180; |
tea5062001 | 0:c94b2f0a4409 | 1860 | |
tea5062001 | 0:c94b2f0a4409 | 1861 | // Sigma = (I - K*H) * Sigma_bar |
tea5062001 | 0:c94b2f0a4409 | 1862 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1863 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1864 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1865 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1866 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1867 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1868 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1869 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1870 | Sigma_bar[2][2] = Sigma_bar[2][2] - Kli[2][0]*Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1871 | |
tea5062001 | 0:c94b2f0a4409 | 1872 | up_check = 2; |
tea5062001 | 0:c94b2f0a4409 | 1873 | break; |
tea5062001 | 0:c94b2f0a4409 | 1874 | } |
tea5062001 | 0:c94b2f0a4409 | 1875 | } |
tea5062001 | 0:c94b2f0a4409 | 1876 | else |
tea5062001 | 0:c94b2f0a4409 | 1877 | { |
tea5062001 | 0:c94b2f0a4409 | 1878 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1879 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1880 | mu_bar[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1881 | |
tea5062001 | 0:c94b2f0a4409 | 1882 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1883 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1884 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1885 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1886 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1887 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1888 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1889 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1890 | Sigma_bar[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1891 | |
tea5062001 | 0:c94b2f0a4409 | 1892 | up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 1893 | } |
tea5062001 | 0:c94b2f0a4409 | 1894 | |
tea5062001 | 0:c94b2f0a4409 | 1895 | up_rot = 0; |
tea5062001 | 0:c94b2f0a4409 | 1896 | } |
tea5062001 | 0:c94b2f0a4409 | 1897 | else |
tea5062001 | 0:c94b2f0a4409 | 1898 | { |
tea5062001 | 0:c94b2f0a4409 | 1899 | mu_bar[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1900 | mu_bar[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1901 | mu_bar[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1902 | |
tea5062001 | 0:c94b2f0a4409 | 1903 | Sigma_bar[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1904 | Sigma_bar[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1905 | Sigma_bar[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1906 | Sigma_bar[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1907 | Sigma_bar[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1908 | Sigma_bar[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1909 | Sigma_bar[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1910 | Sigma_bar[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1911 | Sigma_bar[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1912 | |
tea5062001 | 0:c94b2f0a4409 | 1913 | up_check = 0; |
tea5062001 | 0:c94b2f0a4409 | 1914 | } |
tea5062001 | 0:c94b2f0a4409 | 1915 | |
tea5062001 | 0:c94b2f0a4409 | 1916 | mu[0][0] = mu_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1917 | mu[1][0] = mu_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1918 | mu[2][0] = mu_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1919 | |
tea5062001 | 0:c94b2f0a4409 | 1920 | Sigma[0][0] = Sigma_bar[0][0]; |
tea5062001 | 0:c94b2f0a4409 | 1921 | Sigma[0][1] = Sigma_bar[0][1]; |
tea5062001 | 0:c94b2f0a4409 | 1922 | Sigma[0][2] = Sigma_bar[0][2]; |
tea5062001 | 0:c94b2f0a4409 | 1923 | Sigma[1][0] = Sigma_bar[1][0]; |
tea5062001 | 0:c94b2f0a4409 | 1924 | Sigma[1][1] = Sigma_bar[1][1]; |
tea5062001 | 0:c94b2f0a4409 | 1925 | Sigma[1][2] = Sigma_bar[1][2]; |
tea5062001 | 0:c94b2f0a4409 | 1926 | Sigma[2][0] = Sigma_bar[2][0]; |
tea5062001 | 0:c94b2f0a4409 | 1927 | Sigma[2][1] = Sigma_bar[2][1]; |
tea5062001 | 0:c94b2f0a4409 | 1928 | Sigma[2][2] = Sigma_bar[2][2]; |
tea5062001 | 0:c94b2f0a4409 | 1929 | } |
tea5062001 | 0:c94b2f0a4409 | 1930 | // if(fusion_flag == 1) end |
tea5062001 | 0:c94b2f0a4409 | 1931 | } |
tea5062001 | 0:c94b2f0a4409 | 1932 | |
tea5062001 | 0:c94b2f0a4409 | 1933 | ////////// timer 5 : extended kalman filter //////////////////////////////////////////////////////////////////////////////////// |
tea5062001 | 0:c94b2f0a4409 | 1934 | |
tea5062001 | 0:c94b2f0a4409 | 1935 | // timer 6 : navigation |
tea5062001 | 0:c94b2f0a4409 | 1936 | if((t.read_us() - lastMilli6) >= LOOPTIME6) // 100000 us = 0.1 s |
tea5062001 | 0:c94b2f0a4409 | 1937 | { |
tea5062001 | 0:c94b2f0a4409 | 1938 | lastMilli6 = t.read_us(); |
tea5062001 | 0:c94b2f0a4409 | 1939 | |
tea5062001 | 0:c94b2f0a4409 | 1940 | // range 0~359 deg |
tea5062001 | 0:c94b2f0a4409 | 1941 | mu_th_deg = mu[2][0] * 180/PI; |
tea5062001 | 0:c94b2f0a4409 | 1942 | |
tea5062001 | 0:c94b2f0a4409 | 1943 | if(mu_th_deg < 0) |
tea5062001 | 0:c94b2f0a4409 | 1944 | mu_th_deg = mu_th_deg % 360 + 360; |
tea5062001 | 0:c94b2f0a4409 | 1945 | else |
tea5062001 | 0:c94b2f0a4409 | 1946 | mu_th_deg = mu_th_deg % 360; |
tea5062001 | 0:c94b2f0a4409 | 1947 | |
tea5062001 | 0:c94b2f0a4409 | 1948 | // range -179~180 deg |
tea5062001 | 0:c94b2f0a4409 | 1949 | if(mu_th_deg > 180) |
tea5062001 | 0:c94b2f0a4409 | 1950 | mu_th_deg_180 = mu_th_deg - 360; |
tea5062001 | 0:c94b2f0a4409 | 1951 | else |
tea5062001 | 0:c94b2f0a4409 | 1952 | mu_th_deg_180 = mu_th_deg; |
tea5062001 | 0:c94b2f0a4409 | 1953 | |
tea5062001 | 0:c94b2f0a4409 | 1954 | mu_th_PI = (float)mu_th_deg_180 * PI/180; |
tea5062001 | 0:c94b2f0a4409 | 1955 | |
tea5062001 | 0:c94b2f0a4409 | 1956 | int turn_point = 33; |
tea5062001 | 0:c94b2f0a4409 | 1957 | int end_point = turn_point + 22; |
tea5062001 | 0:c94b2f0a4409 | 1958 | |
tea5062001 | 0:c94b2f0a4409 | 1959 | if(nav_state == 1) |
tea5062001 | 0:c94b2f0a4409 | 1960 | { |
tea5062001 | 0:c94b2f0a4409 | 1961 | Pxd = turn_point*1*block_length; |
tea5062001 | 0:c94b2f0a4409 | 1962 | Pyd = 0*1*block_length; |
tea5062001 | 0:c94b2f0a4409 | 1963 | Od = 0; |
tea5062001 | 0:c94b2f0a4409 | 1964 | } |
tea5062001 | 0:c94b2f0a4409 | 1965 | else if(nav_state == 2) |
tea5062001 | 0:c94b2f0a4409 | 1966 | { |
tea5062001 | 0:c94b2f0a4409 | 1967 | Pxd = turn_point*1*block_length; |
tea5062001 | 0:c94b2f0a4409 | 1968 | Pyd = 0*1*block_length; |
tea5062001 | 0:c94b2f0a4409 | 1969 | Od = PI/2; |
tea5062001 | 0:c94b2f0a4409 | 1970 | } |
tea5062001 | 0:c94b2f0a4409 | 1971 | else if(nav_state == 3) |
tea5062001 | 0:c94b2f0a4409 | 1972 | { |
tea5062001 | 0:c94b2f0a4409 | 1973 | Pxd = turn_point*1*block_length; |
tea5062001 | 0:c94b2f0a4409 | 1974 | Pyd = (1)*(end_point - turn_point)*1*block_length; |
tea5062001 | 0:c94b2f0a4409 | 1975 | Od = PI/2; |
tea5062001 | 0:c94b2f0a4409 | 1976 | } |
tea5062001 | 0:c94b2f0a4409 | 1977 | else if(nav_state == 4) |
tea5062001 | 0:c94b2f0a4409 | 1978 | { |
tea5062001 | 0:c94b2f0a4409 | 1979 | Pxd = turn_point*1*block_length; |
tea5062001 | 0:c94b2f0a4409 | 1980 | Pyd = (1)*(end_point - turn_point)*1*block_length; |
tea5062001 | 0:c94b2f0a4409 | 1981 | Od = PI; |
tea5062001 | 0:c94b2f0a4409 | 1982 | } |
tea5062001 | 0:c94b2f0a4409 | 1983 | |
tea5062001 | 0:c94b2f0a4409 | 1984 | delta_Pxd = mu[0][0] - Pxd; |
tea5062001 | 0:c94b2f0a4409 | 1985 | delta_Pyd = mu[1][0] - Pyd; |
tea5062001 | 0:c94b2f0a4409 | 1986 | delta_Od = mu_th_PI - Od; |
tea5062001 | 0:c94b2f0a4409 | 1987 | |
tea5062001 | 0:c94b2f0a4409 | 1988 | distance_error_P = sqrt(pow(delta_Pxd,2) + pow(delta_Pyd,2)); |
tea5062001 | 0:c94b2f0a4409 | 1989 | error_O = delta_Od; |
tea5062001 | 0:c94b2f0a4409 | 1990 | |
tea5062001 | 0:c94b2f0a4409 | 1991 | //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// |
tea5062001 | 0:c94b2f0a4409 | 1992 | |
tea5062001 | 0:c94b2f0a4409 | 1993 | if((Theta_c >= 70 && Theta_c <= 89) && (Theta_c >= -89 && Theta_c <= -70) && nav_flag == 1 && update_source == 2 && update_source == 1) |
tea5062001 | 0:c94b2f0a4409 | 1994 | { |
tea5062001 | 0:c94b2f0a4409 | 1995 | line_tracker = 1; |
tea5062001 | 0:c94b2f0a4409 | 1996 | } |
tea5062001 | 0:c94b2f0a4409 | 1997 | else |
tea5062001 | 0:c94b2f0a4409 | 1998 | { |
tea5062001 | 0:c94b2f0a4409 | 1999 | line_tracker = 0; |
tea5062001 | 0:c94b2f0a4409 | 2000 | } |
tea5062001 | 0:c94b2f0a4409 | 2001 | |
tea5062001 | 0:c94b2f0a4409 | 2002 | if(nav_state == 2) |
tea5062001 | 0:c94b2f0a4409 | 2003 | { |
tea5062001 | 0:c94b2f0a4409 | 2004 | line_tracker = 0; |
tea5062001 | 0:c94b2f0a4409 | 2005 | } |
tea5062001 | 0:c94b2f0a4409 | 2006 | |
tea5062001 | 0:c94b2f0a4409 | 2007 | if(line_tracker == 1) |
tea5062001 | 0:c94b2f0a4409 | 2008 | { |
tea5062001 | 0:c94b2f0a4409 | 2009 | float K_line_tracker = 0.02; |
tea5062001 | 0:c94b2f0a4409 | 2010 | |
tea5062001 | 0:c94b2f0a4409 | 2011 | if(Theta_c >= 60) {gain_w = -K_line_tracker*(Theta_c - 90);} |
tea5062001 | 0:c94b2f0a4409 | 2012 | else if(Theta_c <= -60) {gain_w = -K_line_tracker*(90 + Theta_c);} |
tea5062001 | 0:c94b2f0a4409 | 2013 | |
tea5062001 | 0:c94b2f0a4409 | 2014 | if(distance_error_P >= 0.39) |
tea5062001 | 0:c94b2f0a4409 | 2015 | { |
tea5062001 | 0:c94b2f0a4409 | 2016 | gain_v = 0.15; |
tea5062001 | 0:c94b2f0a4409 | 2017 | } |
tea5062001 | 0:c94b2f0a4409 | 2018 | else |
tea5062001 | 0:c94b2f0a4409 | 2019 | { |
tea5062001 | 0:c94b2f0a4409 | 2020 | gain_v = -Kv*(delta_Pxd*cos(mu_th_PI) + delta_Pyd*sin(mu_th_PI)); |
tea5062001 | 0:c94b2f0a4409 | 2021 | } |
tea5062001 | 0:c94b2f0a4409 | 2022 | |
tea5062001 | 0:c94b2f0a4409 | 2023 | vel_msg.linear.x = gain_v; |
tea5062001 | 0:c94b2f0a4409 | 2024 | vel_msg.angular.z = gain_w; |
tea5062001 | 0:c94b2f0a4409 | 2025 | p.publish(&vel_msg); |
tea5062001 | 0:c94b2f0a4409 | 2026 | |
tea5062001 | 0:c94b2f0a4409 | 2027 | gain_v = -Kv*(delta_Pxd*cos(mu_th_PI) + delta_Pyd*sin(mu_th_PI)); |
tea5062001 | 0:c94b2f0a4409 | 2028 | gain_w = -Kw*delta_Od; |
tea5062001 | 0:c94b2f0a4409 | 2029 | |
tea5062001 | 0:c94b2f0a4409 | 2030 | if(gain_v >= 0) |
tea5062001 | 0:c94b2f0a4409 | 2031 | error_P = gain_v; |
tea5062001 | 0:c94b2f0a4409 | 2032 | else |
tea5062001 | 0:c94b2f0a4409 | 2033 | error_P = -gain_v; |
tea5062001 | 0:c94b2f0a4409 | 2034 | |
tea5062001 | 0:c94b2f0a4409 | 2035 | if(gain_w >= 0) |
tea5062001 | 0:c94b2f0a4409 | 2036 | error_O = gain_w; |
tea5062001 | 0:c94b2f0a4409 | 2037 | else |
tea5062001 | 0:c94b2f0a4409 | 2038 | error_O = -gain_w; |
tea5062001 | 0:c94b2f0a4409 | 2039 | } |
tea5062001 | 0:c94b2f0a4409 | 2040 | else |
tea5062001 | 0:c94b2f0a4409 | 2041 | { |
tea5062001 | 0:c94b2f0a4409 | 2042 | if(distance_error_P >= 0.39) |
tea5062001 | 0:c94b2f0a4409 | 2043 | { |
tea5062001 | 0:c94b2f0a4409 | 2044 | gain_v = 0.15; |
tea5062001 | 0:c94b2f0a4409 | 2045 | gain_w = -Kw*delta_Od; |
tea5062001 | 0:c94b2f0a4409 | 2046 | } |
tea5062001 | 0:c94b2f0a4409 | 2047 | else |
tea5062001 | 0:c94b2f0a4409 | 2048 | { |
tea5062001 | 0:c94b2f0a4409 | 2049 | gain_v = -Kv*(delta_Pxd*cos(mu_th_PI) + delta_Pyd*sin(mu_th_PI)); |
tea5062001 | 0:c94b2f0a4409 | 2050 | gain_w = -Kw*delta_Od; |
tea5062001 | 0:c94b2f0a4409 | 2051 | } |
tea5062001 | 0:c94b2f0a4409 | 2052 | |
tea5062001 | 0:c94b2f0a4409 | 2053 | if(gain_v >= 0) |
tea5062001 | 0:c94b2f0a4409 | 2054 | error_P = gain_v; |
tea5062001 | 0:c94b2f0a4409 | 2055 | else |
tea5062001 | 0:c94b2f0a4409 | 2056 | error_P = -gain_v; |
tea5062001 | 0:c94b2f0a4409 | 2057 | |
tea5062001 | 0:c94b2f0a4409 | 2058 | if(gain_w >= 0) |
tea5062001 | 0:c94b2f0a4409 | 2059 | error_O = gain_w; |
tea5062001 | 0:c94b2f0a4409 | 2060 | else |
tea5062001 | 0:c94b2f0a4409 | 2061 | error_O = -gain_w; |
tea5062001 | 0:c94b2f0a4409 | 2062 | |
tea5062001 | 0:c94b2f0a4409 | 2063 | if(nav_flag == 1) |
tea5062001 | 0:c94b2f0a4409 | 2064 | { |
tea5062001 | 0:c94b2f0a4409 | 2065 | vel_msg.linear.x = gain_v; |
tea5062001 | 0:c94b2f0a4409 | 2066 | vel_msg.angular.z = gain_w; |
tea5062001 | 0:c94b2f0a4409 | 2067 | p.publish(&vel_msg); |
tea5062001 | 0:c94b2f0a4409 | 2068 | } |
tea5062001 | 0:c94b2f0a4409 | 2069 | |
tea5062001 | 0:c94b2f0a4409 | 2070 | } |
tea5062001 | 0:c94b2f0a4409 | 2071 | |
tea5062001 | 0:c94b2f0a4409 | 2072 | if(error_P < 0.01 && error_O < PI/90) |
tea5062001 | 0:c94b2f0a4409 | 2073 | { |
tea5062001 | 0:c94b2f0a4409 | 2074 | vel_msg.linear.x = 0; |
tea5062001 | 0:c94b2f0a4409 | 2075 | vel_msg.angular.z = 0; |
tea5062001 | 0:c94b2f0a4409 | 2076 | p.publish(&vel_msg); |
tea5062001 | 0:c94b2f0a4409 | 2077 | |
tea5062001 | 0:c94b2f0a4409 | 2078 | nav_state++; |
tea5062001 | 0:c94b2f0a4409 | 2079 | |
tea5062001 | 0:c94b2f0a4409 | 2080 | if(nav_state >= 5) |
tea5062001 | 0:c94b2f0a4409 | 2081 | { |
tea5062001 | 0:c94b2f0a4409 | 2082 | nav_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 2083 | nav_state = 0; |
tea5062001 | 0:c94b2f0a4409 | 2084 | } |
tea5062001 | 0:c94b2f0a4409 | 2085 | } |
tea5062001 | 0:c94b2f0a4409 | 2086 | } |
tea5062001 | 0:c94b2f0a4409 | 2087 | |
tea5062001 | 0:c94b2f0a4409 | 2088 | //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// |
tea5062001 | 0:c94b2f0a4409 | 2089 | |
tea5062001 | 0:c94b2f0a4409 | 2090 | // magnetometer correction |
tea5062001 | 0:c94b2f0a4409 | 2091 | if(cal_flag == 1) |
tea5062001 | 0:c94b2f0a4409 | 2092 | { |
tea5062001 | 0:c94b2f0a4409 | 2093 | magx_max = magx[0]; |
tea5062001 | 0:c94b2f0a4409 | 2094 | magx_min = magx[0]; |
tea5062001 | 0:c94b2f0a4409 | 2095 | magy_max = magy[0]; |
tea5062001 | 0:c94b2f0a4409 | 2096 | magy_min = magy[0]; |
tea5062001 | 0:c94b2f0a4409 | 2097 | |
tea5062001 | 0:c94b2f0a4409 | 2098 | magx_max2 = magx2[0]; |
tea5062001 | 0:c94b2f0a4409 | 2099 | magx_min2 = magx2[0]; |
tea5062001 | 0:c94b2f0a4409 | 2100 | magy_max2 = magy2[0]; |
tea5062001 | 0:c94b2f0a4409 | 2101 | magy_min2 = magy2[0]; |
tea5062001 | 0:c94b2f0a4409 | 2102 | |
tea5062001 | 0:c94b2f0a4409 | 2103 | for(int i = 1 ; i < ind ; i++) |
tea5062001 | 0:c94b2f0a4409 | 2104 | { |
tea5062001 | 0:c94b2f0a4409 | 2105 | if(magx[i] > magx_max) // find x max |
tea5062001 | 0:c94b2f0a4409 | 2106 | magx_max = magx[i]; |
tea5062001 | 0:c94b2f0a4409 | 2107 | if(magx[i] < magx_min) // find x min |
tea5062001 | 0:c94b2f0a4409 | 2108 | magx_min = magx[i]; |
tea5062001 | 0:c94b2f0a4409 | 2109 | if(magy[i] > magy_max) // find y max |
tea5062001 | 0:c94b2f0a4409 | 2110 | magy_max = magy[i]; |
tea5062001 | 0:c94b2f0a4409 | 2111 | if(magy[i] < magy_min) // find y min |
tea5062001 | 0:c94b2f0a4409 | 2112 | magy_min = magy[i]; |
tea5062001 | 0:c94b2f0a4409 | 2113 | |
tea5062001 | 0:c94b2f0a4409 | 2114 | if(magx2[i] > magx_max2) // find x max |
tea5062001 | 0:c94b2f0a4409 | 2115 | magx_max2 = magx2[i]; |
tea5062001 | 0:c94b2f0a4409 | 2116 | if(magx2[i] < magx_min2) // find x min |
tea5062001 | 0:c94b2f0a4409 | 2117 | magx_min2 = magx2[i]; |
tea5062001 | 0:c94b2f0a4409 | 2118 | if(magy2[i] > magy_max2) // find y max |
tea5062001 | 0:c94b2f0a4409 | 2119 | magy_max2 = magy2[i]; |
tea5062001 | 0:c94b2f0a4409 | 2120 | if(magy2[i] < magy_min2) // find y min |
tea5062001 | 0:c94b2f0a4409 | 2121 | magy_min2 = magy2[i]; |
tea5062001 | 0:c94b2f0a4409 | 2122 | } |
tea5062001 | 0:c94b2f0a4409 | 2123 | |
tea5062001 | 0:c94b2f0a4409 | 2124 | magx0 = (magx_max + magx_min) / 2; // center x |
tea5062001 | 0:c94b2f0a4409 | 2125 | magy0 = (magy_max + magy_min) / 2; // center y |
tea5062001 | 0:c94b2f0a4409 | 2126 | |
tea5062001 | 0:c94b2f0a4409 | 2127 | magx02 = (magx_max2 + magx_min2) / 2; // center x |
tea5062001 | 0:c94b2f0a4409 | 2128 | magy02 = (magy_max2 + magy_min2) / 2; // center y |
tea5062001 | 0:c94b2f0a4409 | 2129 | |
tea5062001 | 0:c94b2f0a4409 | 2130 | Magn_axis_zero[0] = magx0; |
tea5062001 | 0:c94b2f0a4409 | 2131 | Magn_axis_zero[1] = magy0; |
tea5062001 | 0:c94b2f0a4409 | 2132 | |
tea5062001 | 0:c94b2f0a4409 | 2133 | Magn_axis_zero2[0] = magx02; |
tea5062001 | 0:c94b2f0a4409 | 2134 | Magn_axis_zero2[1] = magy02; |
tea5062001 | 0:c94b2f0a4409 | 2135 | |
tea5062001 | 0:c94b2f0a4409 | 2136 | a = (magx_max - magx_min) / 2; // long axis |
tea5062001 | 0:c94b2f0a4409 | 2137 | b = (magy_max - magy_min) / 2; // short axis |
tea5062001 | 0:c94b2f0a4409 | 2138 | |
tea5062001 | 0:c94b2f0a4409 | 2139 | a2 = (magx_max2 - magx_min2) / 2; // long axis |
tea5062001 | 0:c94b2f0a4409 | 2140 | b2 = (magy_max2 - magy_min2) / 2; // short axis |
tea5062001 | 0:c94b2f0a4409 | 2141 | |
tea5062001 | 0:c94b2f0a4409 | 2142 | Bex = (Magn_axis_data_f[0] - Magn_axis_zero[0]) / a; |
tea5062001 | 0:c94b2f0a4409 | 2143 | Bey = (Magn_axis_data_f[1] - Magn_axis_zero[1]) / b; |
tea5062001 | 0:c94b2f0a4409 | 2144 | |
tea5062001 | 0:c94b2f0a4409 | 2145 | Bex2 = (Magn_axis_data_f2[0] - Magn_axis_zero2[0]) / a2; |
tea5062001 | 0:c94b2f0a4409 | 2146 | Bey2 = (Magn_axis_data_f2[1] - Magn_axis_zero2[1]) / b2; |
tea5062001 | 0:c94b2f0a4409 | 2147 | |
tea5062001 | 0:c94b2f0a4409 | 2148 | Be = (sqrt(Bex*Bex + Bey*Bey) + sqrt(Bex2*Bex2 + Bey2*Bey2)) / 2; |
tea5062001 | 0:c94b2f0a4409 | 2149 | |
tea5062001 | 0:c94b2f0a4409 | 2150 | cal_flag = 0; // calculate finish |
tea5062001 | 0:c94b2f0a4409 | 2151 | th = 0; |
tea5062001 | 0:c94b2f0a4409 | 2152 | ind = 0; |
tea5062001 | 0:c94b2f0a4409 | 2153 | ind_ = 0; |
tea5062001 | 0:c94b2f0a4409 | 2154 | BK_ = 1; |
tea5062001 | 0:c94b2f0a4409 | 2155 | } |
tea5062001 | 0:c94b2f0a4409 | 2156 | } // while(1) end |
tea5062001 | 0:c94b2f0a4409 | 2157 | } // int main() end |
tea5062001 | 0:c94b2f0a4409 | 2158 | |
tea5062001 | 0:c94b2f0a4409 | 2159 | // Kalman filter and observer ////////////////////////////////////////////////////////////////////////////////////////////// |
tea5062001 | 0:c94b2f0a4409 | 2160 | |
tea5062001 | 0:c94b2f0a4409 | 2161 | void read_sensor(void) |
tea5062001 | 0:c94b2f0a4409 | 2162 | { |
tea5062001 | 0:c94b2f0a4409 | 2163 | // read sensor raw data from LSM9DS0_SH.h |
tea5062001 | 0:c94b2f0a4409 | 2164 | read_IMU(); |
tea5062001 | 0:c94b2f0a4409 | 2165 | |
tea5062001 | 0:c94b2f0a4409 | 2166 | // sensor filter data |
tea5062001 | 0:c94b2f0a4409 | 2167 | // gyro z |
tea5062001 | 0:c94b2f0a4409 | 2168 | Gyro_axis_data_f[2] = lpf(Wz,Gyro_axis_data_f_old[2],10); |
tea5062001 | 0:c94b2f0a4409 | 2169 | Gyro_axis_data_f_old[2] = Gyro_axis_data_f[2]; |
tea5062001 | 0:c94b2f0a4409 | 2170 | |
tea5062001 | 0:c94b2f0a4409 | 2171 | // magn x , magn y , magn z |
tea5062001 | 0:c94b2f0a4409 | 2172 | Magn_axis_data_f[0] = lpf(Mx,Magn_axis_data_f_old[0],12); |
tea5062001 | 0:c94b2f0a4409 | 2173 | Magn_axis_data_f_old[0] = Magn_axis_data_f[0]; |
tea5062001 | 0:c94b2f0a4409 | 2174 | Magn_axis_data_f[1] = lpf(My,Magn_axis_data_f_old[1],12); |
tea5062001 | 0:c94b2f0a4409 | 2175 | Magn_axis_data_f_old[1] = Magn_axis_data_f[1]; |
tea5062001 | 0:c94b2f0a4409 | 2176 | |
tea5062001 | 0:c94b2f0a4409 | 2177 | Magn_axis_data_f2[0] = lpf(M2x,Magn_axis_data_f_old2[0],12); |
tea5062001 | 0:c94b2f0a4409 | 2178 | Magn_axis_data_f_old2[0] = Magn_axis_data_f2[0]; |
tea5062001 | 0:c94b2f0a4409 | 2179 | Magn_axis_data_f2[1] = lpf(M2y,Magn_axis_data_f_old2[1],12); |
tea5062001 | 0:c94b2f0a4409 | 2180 | Magn_axis_data_f_old2[1] = Magn_axis_data_f2[1]; |
tea5062001 | 0:c94b2f0a4409 | 2181 | |
tea5062001 | 0:c94b2f0a4409 | 2182 | // sensor after correction |
tea5062001 | 0:c94b2f0a4409 | 2183 | // gyro z |
tea5062001 | 0:c94b2f0a4409 | 2184 | Gyro_scale[2] = (Gyro_axis_data_f[2] - Gyro_axis_zero[2]); |
tea5062001 | 0:c94b2f0a4409 | 2185 | w_s = Gyro_scale[2]; |
tea5062001 | 0:c94b2f0a4409 | 2186 | |
tea5062001 | 0:c94b2f0a4409 | 2187 | // magn x , magn y |
tea5062001 | 0:c94b2f0a4409 | 2188 | Magn_scale[0] = (Magn_axis_data_f[0] - Magn_axis_zero[0]) / a; |
tea5062001 | 0:c94b2f0a4409 | 2189 | Magn_scale[1] = (Magn_axis_data_f[1] - Magn_axis_zero[1]) / b; |
tea5062001 | 0:c94b2f0a4409 | 2190 | |
tea5062001 | 0:c94b2f0a4409 | 2191 | Magn_scale2[0] = (Magn_axis_data_f2[0] - Magn_axis_zero2[0]) / a2; |
tea5062001 | 0:c94b2f0a4409 | 2192 | Magn_scale2[1] = (Magn_axis_data_f2[1] - Magn_axis_zero2[1]) / b2; |
tea5062001 | 0:c94b2f0a4409 | 2193 | |
tea5062001 | 0:c94b2f0a4409 | 2194 | // trust index |
tea5062001 | 0:c94b2f0a4409 | 2195 | Q = (Magn_scale[0]*Magn_scale2[0] + Magn_scale[1]*Magn_scale2[1]) / (Be * Be); |
tea5062001 | 0:c94b2f0a4409 | 2196 | Q = Q - 1; |
tea5062001 | 0:c94b2f0a4409 | 2197 | |
tea5062001 | 0:c94b2f0a4409 | 2198 | // magnetometer angle |
tea5062001 | 0:c94b2f0a4409 | 2199 | if(Magn_scale[0]>0 && Magn_scale[1]>0) |
tea5062001 | 0:c94b2f0a4409 | 2200 | phi = 2*PI - atan((Magn_scale[1])/(Magn_scale[0])); |
tea5062001 | 0:c94b2f0a4409 | 2201 | else if(Magn_scale[0]<0 && Magn_scale[1]>0) |
tea5062001 | 0:c94b2f0a4409 | 2202 | phi = 2*PI - (PI - atan(-(Magn_scale[1])/(Magn_scale[0]))); |
tea5062001 | 0:c94b2f0a4409 | 2203 | else if(Magn_scale[0]<0 && Magn_scale[1]<0) |
tea5062001 | 0:c94b2f0a4409 | 2204 | phi = 2*PI - (PI + atan((Magn_scale[1])/(Magn_scale[0]))); |
tea5062001 | 0:c94b2f0a4409 | 2205 | else if(Magn_scale[0]>0 && Magn_scale[1]<0) |
tea5062001 | 0:c94b2f0a4409 | 2206 | phi = 2*PI - (2*PI - atan(-(Magn_scale[1])/(Magn_scale[0]))); |
tea5062001 | 0:c94b2f0a4409 | 2207 | |
tea5062001 | 0:c94b2f0a4409 | 2208 | if(Magn_scale2[0]>0 && Magn_scale2[1]>0) |
tea5062001 | 0:c94b2f0a4409 | 2209 | phi2 = 2*PI - atan((Magn_scale2[1])/(Magn_scale2[0])); |
tea5062001 | 0:c94b2f0a4409 | 2210 | else if(Magn_scale2[0]<0 && Magn_scale2[1]>0) |
tea5062001 | 0:c94b2f0a4409 | 2211 | phi2 = 2*PI - (PI - atan(-(Magn_scale2[1])/(Magn_scale2[0]))); |
tea5062001 | 0:c94b2f0a4409 | 2212 | else if(Magn_scale2[0]<0 && Magn_scale2[1]<0) |
tea5062001 | 0:c94b2f0a4409 | 2213 | phi2 = 2*PI - (PI + atan((Magn_scale2[1])/(Magn_scale2[0]))); |
tea5062001 | 0:c94b2f0a4409 | 2214 | else if(Magn_scale2[0]>0 && Magn_scale2[1]<0) |
tea5062001 | 0:c94b2f0a4409 | 2215 | phi2 = 2*PI - (2*PI - atan(-(Magn_scale2[1])/(Magn_scale2[0]))); |
tea5062001 | 0:c94b2f0a4409 | 2216 | |
tea5062001 | 0:c94b2f0a4409 | 2217 | // gyro bias average |
tea5062001 | 0:c94b2f0a4409 | 2218 | if(gyro_flag == 0) |
tea5062001 | 0:c94b2f0a4409 | 2219 | { |
tea5062001 | 0:c94b2f0a4409 | 2220 | gyro_count++; |
tea5062001 | 0:c94b2f0a4409 | 2221 | |
tea5062001 | 0:c94b2f0a4409 | 2222 | if(gyro_count == 150) |
tea5062001 | 0:c94b2f0a4409 | 2223 | { |
tea5062001 | 0:c94b2f0a4409 | 2224 | gyro_init[index_count] = Gyro_axis_data_f[2]; |
tea5062001 | 0:c94b2f0a4409 | 2225 | index_count++; |
tea5062001 | 0:c94b2f0a4409 | 2226 | } |
tea5062001 | 0:c94b2f0a4409 | 2227 | else if(gyro_count == 155) |
tea5062001 | 0:c94b2f0a4409 | 2228 | { |
tea5062001 | 0:c94b2f0a4409 | 2229 | gyro_init[index_count] = Gyro_axis_data_f[2]; |
tea5062001 | 0:c94b2f0a4409 | 2230 | index_count++; |
tea5062001 | 0:c94b2f0a4409 | 2231 | } |
tea5062001 | 0:c94b2f0a4409 | 2232 | else if(gyro_count == 160) |
tea5062001 | 0:c94b2f0a4409 | 2233 | { |
tea5062001 | 0:c94b2f0a4409 | 2234 | gyro_init[index_count] = Gyro_axis_data_f[2]; |
tea5062001 | 0:c94b2f0a4409 | 2235 | index_count++; |
tea5062001 | 0:c94b2f0a4409 | 2236 | } |
tea5062001 | 0:c94b2f0a4409 | 2237 | else if(gyro_count == 165) |
tea5062001 | 0:c94b2f0a4409 | 2238 | { |
tea5062001 | 0:c94b2f0a4409 | 2239 | gyro_init[index_count] = Gyro_axis_data_f[2]; |
tea5062001 | 0:c94b2f0a4409 | 2240 | index_count++; |
tea5062001 | 0:c94b2f0a4409 | 2241 | } |
tea5062001 | 0:c94b2f0a4409 | 2242 | else if(gyro_count == 170) |
tea5062001 | 0:c94b2f0a4409 | 2243 | { |
tea5062001 | 0:c94b2f0a4409 | 2244 | gyro_init[index_count] = Gyro_axis_data_f[2]; |
tea5062001 | 0:c94b2f0a4409 | 2245 | index_count++; |
tea5062001 | 0:c94b2f0a4409 | 2246 | } |
tea5062001 | 0:c94b2f0a4409 | 2247 | else if(gyro_count == 175) |
tea5062001 | 0:c94b2f0a4409 | 2248 | { |
tea5062001 | 0:c94b2f0a4409 | 2249 | gyro_init[index_count] = Gyro_axis_data_f[2]; |
tea5062001 | 0:c94b2f0a4409 | 2250 | index_count++; |
tea5062001 | 0:c94b2f0a4409 | 2251 | } |
tea5062001 | 0:c94b2f0a4409 | 2252 | else if(gyro_count == 180) |
tea5062001 | 0:c94b2f0a4409 | 2253 | { |
tea5062001 | 0:c94b2f0a4409 | 2254 | gyro_init[index_count] = Gyro_axis_data_f[2]; |
tea5062001 | 0:c94b2f0a4409 | 2255 | index_count++; |
tea5062001 | 0:c94b2f0a4409 | 2256 | } |
tea5062001 | 0:c94b2f0a4409 | 2257 | else if(gyro_count == 185) |
tea5062001 | 0:c94b2f0a4409 | 2258 | { |
tea5062001 | 0:c94b2f0a4409 | 2259 | gyro_init[index_count] = Gyro_axis_data_f[2]; |
tea5062001 | 0:c94b2f0a4409 | 2260 | index_count++; |
tea5062001 | 0:c94b2f0a4409 | 2261 | } |
tea5062001 | 0:c94b2f0a4409 | 2262 | else if(gyro_count == 190) |
tea5062001 | 0:c94b2f0a4409 | 2263 | { |
tea5062001 | 0:c94b2f0a4409 | 2264 | gyro_init[index_count] = Gyro_axis_data_f[2]; |
tea5062001 | 0:c94b2f0a4409 | 2265 | index_count++; |
tea5062001 | 0:c94b2f0a4409 | 2266 | } |
tea5062001 | 0:c94b2f0a4409 | 2267 | else if(gyro_count >= 195) |
tea5062001 | 0:c94b2f0a4409 | 2268 | { |
tea5062001 | 0:c94b2f0a4409 | 2269 | gyro_init[index_count] = Gyro_axis_data_f[2]; |
tea5062001 | 0:c94b2f0a4409 | 2270 | int z = 0; |
tea5062001 | 0:c94b2f0a4409 | 2271 | for(z=0 ; z<10 ; z++) |
tea5062001 | 0:c94b2f0a4409 | 2272 | gyro_sum = gyro_sum + gyro_init[z]; |
tea5062001 | 0:c94b2f0a4409 | 2273 | |
tea5062001 | 0:c94b2f0a4409 | 2274 | Gyro_axis_zero[2] = gyro_sum / 10; |
tea5062001 | 0:c94b2f0a4409 | 2275 | index_count = 0; |
tea5062001 | 0:c94b2f0a4409 | 2276 | gyro_count = 0; |
tea5062001 | 0:c94b2f0a4409 | 2277 | gyro_flag = 1; |
tea5062001 | 0:c94b2f0a4409 | 2278 | } |
tea5062001 | 0:c94b2f0a4409 | 2279 | } |
tea5062001 | 0:c94b2f0a4409 | 2280 | |
tea5062001 | 0:c94b2f0a4409 | 2281 | if(gyro_flag == 1) |
tea5062001 | 0:c94b2f0a4409 | 2282 | { |
tea5062001 | 0:c94b2f0a4409 | 2283 | // w_s deadzone |
tea5062001 | 0:c94b2f0a4409 | 2284 | int flag_d_1 = 0; |
tea5062001 | 0:c94b2f0a4409 | 2285 | int flag_d_2 = 0; |
tea5062001 | 0:c94b2f0a4409 | 2286 | flag_d_1 = w_s <= 0.006; |
tea5062001 | 0:c94b2f0a4409 | 2287 | flag_d_2 = w_s >= -0.006; |
tea5062001 | 0:c94b2f0a4409 | 2288 | |
tea5062001 | 0:c94b2f0a4409 | 2289 | if((flag_d_1 + flag_d_2) == 2) |
tea5062001 | 0:c94b2f0a4409 | 2290 | w_s_d = 0; |
tea5062001 | 0:c94b2f0a4409 | 2291 | else |
tea5062001 | 0:c94b2f0a4409 | 2292 | w_s_d = w_s; |
tea5062001 | 0:c94b2f0a4409 | 2293 | |
tea5062001 | 0:c94b2f0a4409 | 2294 | // w_s_d integral |
tea5062001 | 0:c94b2f0a4409 | 2295 | theta_s = theta_s + T*w_s_d; |
tea5062001 | 0:c94b2f0a4409 | 2296 | |
tea5062001 | 0:c94b2f0a4409 | 2297 | // theta_s_deg range 0~359 deg |
tea5062001 | 0:c94b2f0a4409 | 2298 | theta_s_deg = theta_s * 180/PI; |
tea5062001 | 0:c94b2f0a4409 | 2299 | |
tea5062001 | 0:c94b2f0a4409 | 2300 | if(theta_s_deg < 0) |
tea5062001 | 0:c94b2f0a4409 | 2301 | theta_s_deg = theta_s_deg % 360 + 360; |
tea5062001 | 0:c94b2f0a4409 | 2302 | else |
tea5062001 | 0:c94b2f0a4409 | 2303 | theta_s_deg = theta_s_deg % 360; |
tea5062001 | 0:c94b2f0a4409 | 2304 | } |
tea5062001 | 0:c94b2f0a4409 | 2305 | |
tea5062001 | 0:c94b2f0a4409 | 2306 | // phi initialize |
tea5062001 | 0:c94b2f0a4409 | 2307 | if(phi_init_flag == 1) |
tea5062001 | 0:c94b2f0a4409 | 2308 | { |
tea5062001 | 0:c94b2f0a4409 | 2309 | phi_init_count++; |
tea5062001 | 0:c94b2f0a4409 | 2310 | |
tea5062001 | 0:c94b2f0a4409 | 2311 | if(phi_init_count >= 200) |
tea5062001 | 0:c94b2f0a4409 | 2312 | { |
tea5062001 | 0:c94b2f0a4409 | 2313 | // take current phi data for reseting absolute orientation to zero |
tea5062001 | 0:c94b2f0a4409 | 2314 | phi_init = phi; |
tea5062001 | 0:c94b2f0a4409 | 2315 | phi_init2 = phi2; |
tea5062001 | 0:c94b2f0a4409 | 2316 | |
tea5062001 | 0:c94b2f0a4409 | 2317 | // reset KF and observer data |
tea5062001 | 0:c94b2f0a4409 | 2318 | phi_m_a_deg = 0; |
tea5062001 | 0:c94b2f0a4409 | 2319 | phi_m2_a_deg = 0; |
tea5062001 | 0:c94b2f0a4409 | 2320 | jump_count = 0; |
tea5062001 | 0:c94b2f0a4409 | 2321 | jump_count2 = 0; |
tea5062001 | 0:c94b2f0a4409 | 2322 | phi_m_deg_1 = 0; |
tea5062001 | 0:c94b2f0a4409 | 2323 | phi_m2_deg_1 = 0; |
tea5062001 | 0:c94b2f0a4409 | 2324 | phi_m_deg_2 = 0; |
tea5062001 | 0:c94b2f0a4409 | 2325 | phi_m2_deg_2 = 0; |
tea5062001 | 0:c94b2f0a4409 | 2326 | phi_m_a_avg = 0; |
tea5062001 | 0:c94b2f0a4409 | 2327 | theta_s = 0; |
tea5062001 | 0:c94b2f0a4409 | 2328 | theta_me = 0; |
tea5062001 | 0:c94b2f0a4409 | 2329 | theta_fu = 0; |
tea5062001 | 0:c94b2f0a4409 | 2330 | theta_fu_old = 0; |
tea5062001 | 0:c94b2f0a4409 | 2331 | bias = 0; |
tea5062001 | 0:c94b2f0a4409 | 2332 | bias_old = 0; |
tea5062001 | 0:c94b2f0a4409 | 2333 | y = 0; |
tea5062001 | 0:c94b2f0a4409 | 2334 | |
tea5062001 | 0:c94b2f0a4409 | 2335 | // encoder odometry reset |
tea5062001 | 0:c94b2f0a4409 | 2336 | x = 0; |
tea5062001 | 0:c94b2f0a4409 | 2337 | y_ = 0; |
tea5062001 | 0:c94b2f0a4409 | 2338 | th = 0; |
tea5062001 | 0:c94b2f0a4409 | 2339 | x_enc = 0; |
tea5062001 | 0:c94b2f0a4409 | 2340 | y_enc = 0; |
tea5062001 | 0:c94b2f0a4409 | 2341 | th_enc = 0; |
tea5062001 | 0:c94b2f0a4409 | 2342 | x_emg = 0; |
tea5062001 | 0:c94b2f0a4409 | 2343 | y_emg = 0; |
tea5062001 | 0:c94b2f0a4409 | 2344 | th_emg = 0; |
tea5062001 | 0:c94b2f0a4409 | 2345 | |
tea5062001 | 0:c94b2f0a4409 | 2346 | // reset EKF data |
tea5062001 | 0:c94b2f0a4409 | 2347 | for(int i = 0 ; i < 3 ; i++) |
tea5062001 | 0:c94b2f0a4409 | 2348 | { |
tea5062001 | 0:c94b2f0a4409 | 2349 | mu_bar[i][0] = 0; |
tea5062001 | 0:c94b2f0a4409 | 2350 | mu[i][0] = 0; |
tea5062001 | 0:c94b2f0a4409 | 2351 | |
tea5062001 | 0:c94b2f0a4409 | 2352 | for(int j = 0 ; j < 3 ; j++) |
tea5062001 | 0:c94b2f0a4409 | 2353 | { |
tea5062001 | 0:c94b2f0a4409 | 2354 | Sigma_bar[i][j] = 0; |
tea5062001 | 0:c94b2f0a4409 | 2355 | Sigma[i][j] = 0; |
tea5062001 | 0:c94b2f0a4409 | 2356 | } |
tea5062001 | 0:c94b2f0a4409 | 2357 | } |
tea5062001 | 0:c94b2f0a4409 | 2358 | |
tea5062001 | 0:c94b2f0a4409 | 2359 | // stop initialization |
tea5062001 | 0:c94b2f0a4409 | 2360 | phi_init_count = 0; |
tea5062001 | 0:c94b2f0a4409 | 2361 | phi_init_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 2362 | |
tea5062001 | 0:c94b2f0a4409 | 2363 | // start fusion |
tea5062001 | 0:c94b2f0a4409 | 2364 | fusion_flag = 1; |
tea5062001 | 0:c94b2f0a4409 | 2365 | B_ = 1; // dark |
tea5062001 | 0:c94b2f0a4409 | 2366 | } |
tea5062001 | 0:c94b2f0a4409 | 2367 | } |
tea5062001 | 0:c94b2f0a4409 | 2368 | |
tea5062001 | 0:c94b2f0a4409 | 2369 | // phi_m_deg range 0~359 deg |
tea5062001 | 0:c94b2f0a4409 | 2370 | phi_m = phi - phi_init; |
tea5062001 | 0:c94b2f0a4409 | 2371 | phi_m_deg = phi_m * 180/PI; |
tea5062001 | 0:c94b2f0a4409 | 2372 | |
tea5062001 | 0:c94b2f0a4409 | 2373 | if(phi_m_deg < 0) |
tea5062001 | 0:c94b2f0a4409 | 2374 | phi_m_deg = phi_m_deg % 360 + 360; |
tea5062001 | 0:c94b2f0a4409 | 2375 | else |
tea5062001 | 0:c94b2f0a4409 | 2376 | phi_m_deg = phi_m_deg % 360; |
tea5062001 | 0:c94b2f0a4409 | 2377 | |
tea5062001 | 0:c94b2f0a4409 | 2378 | phi_m2 = phi2 - phi_init2; |
tea5062001 | 0:c94b2f0a4409 | 2379 | phi_m2_deg = phi_m2 * 180/PI; |
tea5062001 | 0:c94b2f0a4409 | 2380 | |
tea5062001 | 0:c94b2f0a4409 | 2381 | if(phi_m2_deg < 0) |
tea5062001 | 0:c94b2f0a4409 | 2382 | phi_m2_deg = phi_m2_deg % 360 + 360; |
tea5062001 | 0:c94b2f0a4409 | 2383 | else |
tea5062001 | 0:c94b2f0a4409 | 2384 | phi_m2_deg = phi_m2_deg % 360; |
tea5062001 | 0:c94b2f0a4409 | 2385 | |
tea5062001 | 0:c94b2f0a4409 | 2386 | // phi_m_a accumulate form |
tea5062001 | 0:c94b2f0a4409 | 2387 | diff_phi_count++; |
tea5062001 | 0:c94b2f0a4409 | 2388 | |
tea5062001 | 0:c94b2f0a4409 | 2389 | if(diff_phi_flag == 0) |
tea5062001 | 0:c94b2f0a4409 | 2390 | { |
tea5062001 | 0:c94b2f0a4409 | 2391 | phi_m_deg_1 = phi_m_deg; |
tea5062001 | 0:c94b2f0a4409 | 2392 | phi_m2_deg_1 = phi_m2_deg; |
tea5062001 | 0:c94b2f0a4409 | 2393 | diff_phi_flag = 1; |
tea5062001 | 0:c94b2f0a4409 | 2394 | } |
tea5062001 | 0:c94b2f0a4409 | 2395 | else if(diff_phi_flag == 1) |
tea5062001 | 0:c94b2f0a4409 | 2396 | { |
tea5062001 | 0:c94b2f0a4409 | 2397 | if(diff_phi_count >= 2) |
tea5062001 | 0:c94b2f0a4409 | 2398 | { |
tea5062001 | 0:c94b2f0a4409 | 2399 | phi_m_deg_2 = phi_m_deg + 360*jump_count; |
tea5062001 | 0:c94b2f0a4409 | 2400 | phi_m_deg_T = phi_m_deg_2 - phi_m_deg_1; |
tea5062001 | 0:c94b2f0a4409 | 2401 | |
tea5062001 | 0:c94b2f0a4409 | 2402 | if(phi_m_deg_T <= -300) |
tea5062001 | 0:c94b2f0a4409 | 2403 | { |
tea5062001 | 0:c94b2f0a4409 | 2404 | phi_m_a_deg = phi_m_deg_2 + 360; |
tea5062001 | 0:c94b2f0a4409 | 2405 | phi_m_deg_1 = phi_m_a_deg; |
tea5062001 | 0:c94b2f0a4409 | 2406 | jump_count++; |
tea5062001 | 0:c94b2f0a4409 | 2407 | } |
tea5062001 | 0:c94b2f0a4409 | 2408 | else if(phi_m_deg_T >= 300) |
tea5062001 | 0:c94b2f0a4409 | 2409 | { |
tea5062001 | 0:c94b2f0a4409 | 2410 | phi_m_a_deg = phi_m_deg_2 - 360; |
tea5062001 | 0:c94b2f0a4409 | 2411 | phi_m_deg_1 = phi_m_a_deg; |
tea5062001 | 0:c94b2f0a4409 | 2412 | jump_count--; |
tea5062001 | 0:c94b2f0a4409 | 2413 | } |
tea5062001 | 0:c94b2f0a4409 | 2414 | else |
tea5062001 | 0:c94b2f0a4409 | 2415 | { |
tea5062001 | 0:c94b2f0a4409 | 2416 | phi_m_a_deg = phi_m_deg_2; |
tea5062001 | 0:c94b2f0a4409 | 2417 | phi_m_deg_1 = phi_m_a_deg; |
tea5062001 | 0:c94b2f0a4409 | 2418 | } |
tea5062001 | 0:c94b2f0a4409 | 2419 | |
tea5062001 | 0:c94b2f0a4409 | 2420 | phi_m_a = phi_m_a_deg * PI/180; |
tea5062001 | 0:c94b2f0a4409 | 2421 | |
tea5062001 | 0:c94b2f0a4409 | 2422 | //////////////////////////////////////////////////////////////////// |
tea5062001 | 0:c94b2f0a4409 | 2423 | |
tea5062001 | 0:c94b2f0a4409 | 2424 | phi_m2_deg_2 = phi_m2_deg + 360*jump_count2; |
tea5062001 | 0:c94b2f0a4409 | 2425 | phi_m2_deg_T = phi_m2_deg_2 - phi_m2_deg_1; |
tea5062001 | 0:c94b2f0a4409 | 2426 | |
tea5062001 | 0:c94b2f0a4409 | 2427 | if(phi_m2_deg_T <= -300) |
tea5062001 | 0:c94b2f0a4409 | 2428 | { |
tea5062001 | 0:c94b2f0a4409 | 2429 | phi_m2_a_deg = phi_m2_deg_2 + 360; |
tea5062001 | 0:c94b2f0a4409 | 2430 | phi_m2_deg_1 = phi_m2_a_deg; |
tea5062001 | 0:c94b2f0a4409 | 2431 | jump_count2++; |
tea5062001 | 0:c94b2f0a4409 | 2432 | } |
tea5062001 | 0:c94b2f0a4409 | 2433 | else if(phi_m2_deg_T >= 300) |
tea5062001 | 0:c94b2f0a4409 | 2434 | { |
tea5062001 | 0:c94b2f0a4409 | 2435 | phi_m2_a_deg = phi_m2_deg_2 - 360; |
tea5062001 | 0:c94b2f0a4409 | 2436 | phi_m2_deg_1 = phi_m2_a_deg; |
tea5062001 | 0:c94b2f0a4409 | 2437 | jump_count2--; |
tea5062001 | 0:c94b2f0a4409 | 2438 | } |
tea5062001 | 0:c94b2f0a4409 | 2439 | else |
tea5062001 | 0:c94b2f0a4409 | 2440 | { |
tea5062001 | 0:c94b2f0a4409 | 2441 | phi_m2_a_deg = phi_m2_deg_2; |
tea5062001 | 0:c94b2f0a4409 | 2442 | phi_m2_deg_1 = phi_m2_a_deg; |
tea5062001 | 0:c94b2f0a4409 | 2443 | } |
tea5062001 | 0:c94b2f0a4409 | 2444 | |
tea5062001 | 0:c94b2f0a4409 | 2445 | phi_m2_a = phi_m2_a_deg * PI/180; |
tea5062001 | 0:c94b2f0a4409 | 2446 | |
tea5062001 | 0:c94b2f0a4409 | 2447 | phi_m_a_avg = 0.7*phi_m_a + 0.3*phi_m2_a; |
tea5062001 | 0:c94b2f0a4409 | 2448 | |
tea5062001 | 0:c94b2f0a4409 | 2449 | diff_phi_count = 0; |
tea5062001 | 0:c94b2f0a4409 | 2450 | } |
tea5062001 | 0:c94b2f0a4409 | 2451 | } |
tea5062001 | 0:c94b2f0a4409 | 2452 | |
tea5062001 | 0:c94b2f0a4409 | 2453 | // theta_me Kalman filter |
tea5062001 | 0:c94b2f0a4409 | 2454 | // prediction |
tea5062001 | 0:c94b2f0a4409 | 2455 | theta_me_bar = At*theta_me + Bt*omega_z; |
tea5062001 | 0:c94b2f0a4409 | 2456 | sigma_bar = At*sigma*At + Rt; |
tea5062001 | 0:c94b2f0a4409 | 2457 | |
tea5062001 | 0:c94b2f0a4409 | 2458 | if(Q >= -0.009 && Q <= 0.009) |
tea5062001 | 0:c94b2f0a4409 | 2459 | { |
tea5062001 | 0:c94b2f0a4409 | 2460 | if(Q >= 0) |
tea5062001 | 0:c94b2f0a4409 | 2461 | V = 0.74*Q; |
tea5062001 | 0:c94b2f0a4409 | 2462 | else |
tea5062001 | 0:c94b2f0a4409 | 2463 | V = -1.13*Q; |
tea5062001 | 0:c94b2f0a4409 | 2464 | |
tea5062001 | 0:c94b2f0a4409 | 2465 | update_flag = 1; |
tea5062001 | 0:c94b2f0a4409 | 2466 | G_ = 0; |
tea5062001 | 0:c94b2f0a4409 | 2467 | } |
tea5062001 | 0:c94b2f0a4409 | 2468 | else |
tea5062001 | 0:c94b2f0a4409 | 2469 | { |
tea5062001 | 0:c94b2f0a4409 | 2470 | update_flag = 0; |
tea5062001 | 0:c94b2f0a4409 | 2471 | G_ = 1; |
tea5062001 | 0:c94b2f0a4409 | 2472 | } |
tea5062001 | 0:c94b2f0a4409 | 2473 | |
tea5062001 | 0:c94b2f0a4409 | 2474 | // update distance |
tea5062001 | 0:c94b2f0a4409 | 2475 | update_distance = update_distance + T*vel_x; |
tea5062001 | 0:c94b2f0a4409 | 2476 | update_rotation = update_rotation + T*omega_z; |
tea5062001 | 0:c94b2f0a4409 | 2477 | |
tea5062001 | 0:c94b2f0a4409 | 2478 | if(update_distance >= 0.1) |
tea5062001 | 0:c94b2f0a4409 | 2479 | { |
tea5062001 | 0:c94b2f0a4409 | 2480 | // update |
tea5062001 | 0:c94b2f0a4409 | 2481 | if(update_flag == 1) |
tea5062001 | 0:c94b2f0a4409 | 2482 | { |
tea5062001 | 0:c94b2f0a4409 | 2483 | K = sigma_bar*Ct / (Ct*sigma_bar*Ct + V); |
tea5062001 | 0:c94b2f0a4409 | 2484 | theta_me = theta_me_bar + K*(phi_m_a_avg - Ct*theta_me_bar); |
tea5062001 | 0:c94b2f0a4409 | 2485 | sigma = (1 - K*Ct)*sigma_bar; |
tea5062001 | 0:c94b2f0a4409 | 2486 | } |
tea5062001 | 0:c94b2f0a4409 | 2487 | else |
tea5062001 | 0:c94b2f0a4409 | 2488 | { |
tea5062001 | 0:c94b2f0a4409 | 2489 | theta_me = theta_me_bar; |
tea5062001 | 0:c94b2f0a4409 | 2490 | sigma = sigma_bar; |
tea5062001 | 0:c94b2f0a4409 | 2491 | } |
tea5062001 | 0:c94b2f0a4409 | 2492 | |
tea5062001 | 0:c94b2f0a4409 | 2493 | update_distance = 0; |
tea5062001 | 0:c94b2f0a4409 | 2494 | } |
tea5062001 | 0:c94b2f0a4409 | 2495 | else if(update_distance <= -0.1) |
tea5062001 | 0:c94b2f0a4409 | 2496 | { |
tea5062001 | 0:c94b2f0a4409 | 2497 | // update |
tea5062001 | 0:c94b2f0a4409 | 2498 | if(update_flag == 1) |
tea5062001 | 0:c94b2f0a4409 | 2499 | { |
tea5062001 | 0:c94b2f0a4409 | 2500 | K = sigma_bar*Ct / (Ct*sigma_bar*Ct + V); |
tea5062001 | 0:c94b2f0a4409 | 2501 | theta_me = theta_me_bar + K*(phi_m_a_avg - Ct*theta_me_bar); |
tea5062001 | 0:c94b2f0a4409 | 2502 | sigma = (1 - K*Ct)*sigma_bar; |
tea5062001 | 0:c94b2f0a4409 | 2503 | } |
tea5062001 | 0:c94b2f0a4409 | 2504 | else |
tea5062001 | 0:c94b2f0a4409 | 2505 | { |
tea5062001 | 0:c94b2f0a4409 | 2506 | theta_me = theta_me_bar; |
tea5062001 | 0:c94b2f0a4409 | 2507 | sigma = sigma_bar; |
tea5062001 | 0:c94b2f0a4409 | 2508 | } |
tea5062001 | 0:c94b2f0a4409 | 2509 | |
tea5062001 | 0:c94b2f0a4409 | 2510 | update_distance = 0; |
tea5062001 | 0:c94b2f0a4409 | 2511 | } |
tea5062001 | 0:c94b2f0a4409 | 2512 | else if(update_rotation >= PI/8) |
tea5062001 | 0:c94b2f0a4409 | 2513 | { |
tea5062001 | 0:c94b2f0a4409 | 2514 | // update |
tea5062001 | 0:c94b2f0a4409 | 2515 | if(update_flag == 1) |
tea5062001 | 0:c94b2f0a4409 | 2516 | { |
tea5062001 | 0:c94b2f0a4409 | 2517 | K = sigma_bar*Ct / (Ct*sigma_bar*Ct + V); |
tea5062001 | 0:c94b2f0a4409 | 2518 | theta_me = theta_me_bar + K*(phi_m_a_avg - Ct*theta_me_bar); |
tea5062001 | 0:c94b2f0a4409 | 2519 | sigma = (1 - K*Ct)*sigma_bar; |
tea5062001 | 0:c94b2f0a4409 | 2520 | } |
tea5062001 | 0:c94b2f0a4409 | 2521 | else |
tea5062001 | 0:c94b2f0a4409 | 2522 | { |
tea5062001 | 0:c94b2f0a4409 | 2523 | theta_me = theta_me_bar; |
tea5062001 | 0:c94b2f0a4409 | 2524 | sigma = sigma_bar; |
tea5062001 | 0:c94b2f0a4409 | 2525 | } |
tea5062001 | 0:c94b2f0a4409 | 2526 | |
tea5062001 | 0:c94b2f0a4409 | 2527 | update_rotation = 0; |
tea5062001 | 0:c94b2f0a4409 | 2528 | } |
tea5062001 | 0:c94b2f0a4409 | 2529 | else if(update_rotation <= -PI/8) |
tea5062001 | 0:c94b2f0a4409 | 2530 | { |
tea5062001 | 0:c94b2f0a4409 | 2531 | // update |
tea5062001 | 0:c94b2f0a4409 | 2532 | if(update_flag == 1) |
tea5062001 | 0:c94b2f0a4409 | 2533 | { |
tea5062001 | 0:c94b2f0a4409 | 2534 | K = sigma_bar*Ct / (Ct*sigma_bar*Ct + V); |
tea5062001 | 0:c94b2f0a4409 | 2535 | theta_me = theta_me_bar + K*(phi_m_a_avg - Ct*theta_me_bar); |
tea5062001 | 0:c94b2f0a4409 | 2536 | sigma = (1 - K*Ct)*sigma_bar; |
tea5062001 | 0:c94b2f0a4409 | 2537 | } |
tea5062001 | 0:c94b2f0a4409 | 2538 | else |
tea5062001 | 0:c94b2f0a4409 | 2539 | { |
tea5062001 | 0:c94b2f0a4409 | 2540 | theta_me = theta_me_bar; |
tea5062001 | 0:c94b2f0a4409 | 2541 | sigma = sigma_bar; |
tea5062001 | 0:c94b2f0a4409 | 2542 | } |
tea5062001 | 0:c94b2f0a4409 | 2543 | |
tea5062001 | 0:c94b2f0a4409 | 2544 | update_rotation = 0; |
tea5062001 | 0:c94b2f0a4409 | 2545 | } |
tea5062001 | 0:c94b2f0a4409 | 2546 | else |
tea5062001 | 0:c94b2f0a4409 | 2547 | { |
tea5062001 | 0:c94b2f0a4409 | 2548 | theta_me = theta_me_bar; |
tea5062001 | 0:c94b2f0a4409 | 2549 | sigma = sigma_bar; |
tea5062001 | 0:c94b2f0a4409 | 2550 | } |
tea5062001 | 0:c94b2f0a4409 | 2551 | |
tea5062001 | 0:c94b2f0a4409 | 2552 | // theta_me_deg range 0~359 deg |
tea5062001 | 0:c94b2f0a4409 | 2553 | theta_me_deg = theta_me * 180/PI; |
tea5062001 | 0:c94b2f0a4409 | 2554 | |
tea5062001 | 0:c94b2f0a4409 | 2555 | if(theta_me_deg < 0) |
tea5062001 | 0:c94b2f0a4409 | 2556 | theta_me_deg = theta_me_deg % 360 + 360; |
tea5062001 | 0:c94b2f0a4409 | 2557 | else |
tea5062001 | 0:c94b2f0a4409 | 2558 | theta_me_deg = theta_me_deg % 360; |
tea5062001 | 0:c94b2f0a4409 | 2559 | |
tea5062001 | 0:c94b2f0a4409 | 2560 | // theta_e_deg range 0~359 deg |
tea5062001 | 0:c94b2f0a4409 | 2561 | th_deg = th * 180/PI; |
tea5062001 | 0:c94b2f0a4409 | 2562 | |
tea5062001 | 0:c94b2f0a4409 | 2563 | if(th_deg < 0) |
tea5062001 | 0:c94b2f0a4409 | 2564 | th_deg = th_deg % 360 + 360; |
tea5062001 | 0:c94b2f0a4409 | 2565 | else |
tea5062001 | 0:c94b2f0a4409 | 2566 | th_deg = th_deg % 360; |
tea5062001 | 0:c94b2f0a4409 | 2567 | |
tea5062001 | 0:c94b2f0a4409 | 2568 | if(fusion_flag == 1) |
tea5062001 | 0:c94b2f0a4409 | 2569 | { |
tea5062001 | 0:c94b2f0a4409 | 2570 | // Kalman filter |
tea5062001 | 0:c94b2f0a4409 | 2571 | L1 = 7; |
tea5062001 | 0:c94b2f0a4409 | 2572 | L2 = 13; |
tea5062001 | 0:c94b2f0a4409 | 2573 | |
tea5062001 | 0:c94b2f0a4409 | 2574 | y = theta_me; |
tea5062001 | 0:c94b2f0a4409 | 2575 | |
tea5062001 | 0:c94b2f0a4409 | 2576 | if(bias_flag == 1) |
tea5062001 | 0:c94b2f0a4409 | 2577 | bias_add = bias_add - r_01*r_01*0.000001 + r_01*0.000000000001; |
tea5062001 | 0:c94b2f0a4409 | 2578 | else |
tea5062001 | 0:c94b2f0a4409 | 2579 | bias_add = 0; |
tea5062001 | 0:c94b2f0a4409 | 2580 | |
tea5062001 | 0:c94b2f0a4409 | 2581 | // sensor fusion algorithm |
tea5062001 | 0:c94b2f0a4409 | 2582 | theta_fu = (theta_fu_old + T*(w_s_d + bias_add) + L1*T*y + T*bias) / (1 + L1*T); |
tea5062001 | 0:c94b2f0a4409 | 2583 | theta_fu_old = theta_fu; |
tea5062001 | 0:c94b2f0a4409 | 2584 | |
tea5062001 | 0:c94b2f0a4409 | 2585 | bias = bias_old + L2*T*(y - theta_fu); |
tea5062001 | 0:c94b2f0a4409 | 2586 | bias_old = bias; |
tea5062001 | 0:c94b2f0a4409 | 2587 | |
tea5062001 | 0:c94b2f0a4409 | 2588 | // theta_fu_deg range 0~359 deg |
tea5062001 | 0:c94b2f0a4409 | 2589 | theta_fu_deg = theta_fu * 180/PI; |
tea5062001 | 0:c94b2f0a4409 | 2590 | |
tea5062001 | 0:c94b2f0a4409 | 2591 | if(theta_fu_deg < 0) |
tea5062001 | 0:c94b2f0a4409 | 2592 | theta_fu_deg = theta_fu_deg % 360 + 360; |
tea5062001 | 0:c94b2f0a4409 | 2593 | else |
tea5062001 | 0:c94b2f0a4409 | 2594 | theta_fu_deg = theta_fu_deg % 360; |
tea5062001 | 0:c94b2f0a4409 | 2595 | |
tea5062001 | 0:c94b2f0a4409 | 2596 | // theta_fu_deg_180 range -179~180 deg |
tea5062001 | 0:c94b2f0a4409 | 2597 | if(theta_fu_deg > 180) |
tea5062001 | 0:c94b2f0a4409 | 2598 | theta_fu_deg_180 = theta_fu_deg - 360; |
tea5062001 | 0:c94b2f0a4409 | 2599 | else |
tea5062001 | 0:c94b2f0a4409 | 2600 | theta_fu_deg_180 = theta_fu_deg; |
tea5062001 | 0:c94b2f0a4409 | 2601 | |
tea5062001 | 0:c94b2f0a4409 | 2602 | theta_fu_PI = (float)theta_fu_deg_180 * PI/180; |
tea5062001 | 0:c94b2f0a4409 | 2603 | } // if(fusion_flag == 1) end |
tea5062001 | 0:c94b2f0a4409 | 2604 | } |
tea5062001 | 0:c94b2f0a4409 | 2605 | |
tea5062001 | 0:c94b2f0a4409 | 2606 | // Kalman filter and observer ////////////////////////////////////////////////////////////////////////////////////////////// |
tea5062001 | 0:c94b2f0a4409 | 2607 | |
tea5062001 | 0:c94b2f0a4409 | 2608 | float lpf(float input, float output_old, float frequency) |
tea5062001 | 0:c94b2f0a4409 | 2609 | { |
tea5062001 | 0:c94b2f0a4409 | 2610 | float output = 0; |
tea5062001 | 0:c94b2f0a4409 | 2611 | |
tea5062001 | 0:c94b2f0a4409 | 2612 | output = (output_old + frequency*T*input) / (1 + frequency*T); |
tea5062001 | 0:c94b2f0a4409 | 2613 | |
tea5062001 | 0:c94b2f0a4409 | 2614 | return output; |
tea5062001 | 0:c94b2f0a4409 | 2615 | } |