mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-06-04 21:23:57 +08:00
Merge branch 'master' into fw_control
This commit is contained in:
+2
-1
@@ -1,5 +1,5 @@
|
|||||||
.built
|
.built
|
||||||
.context
|
*.context
|
||||||
.depend
|
.depend
|
||||||
.config
|
.config
|
||||||
.version
|
.version
|
||||||
@@ -10,6 +10,7 @@ apps/namedapp/namedapp_proto.h
|
|||||||
Make.dep
|
Make.dep
|
||||||
*.o
|
*.o
|
||||||
*.a
|
*.a
|
||||||
|
*~
|
||||||
Images/*.bin
|
Images/*.bin
|
||||||
Images/*.px4
|
Images/*.px4
|
||||||
nuttx/Make.defs
|
nuttx/Make.defs
|
||||||
|
|||||||
+5
-3
@@ -20,6 +20,11 @@
|
|||||||
set MODE autostart
|
set MODE autostart
|
||||||
set USB autoconnect
|
set USB autoconnect
|
||||||
|
|
||||||
|
#
|
||||||
|
# Start playing the startup tune
|
||||||
|
#
|
||||||
|
tone_alarm start
|
||||||
|
|
||||||
#
|
#
|
||||||
# Try to mount the microSD card.
|
# Try to mount the microSD card.
|
||||||
#
|
#
|
||||||
@@ -31,9 +36,6 @@ else
|
|||||||
echo "[init] no microSD card found"
|
echo "[init] no microSD card found"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
usleep 500
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Look for an init script on the microSD card.
|
# Look for an init script on the microSD card.
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -286,7 +286,6 @@ int ardrone_interface_thread_main(int argc, char *argv[])
|
|||||||
|
|
||||||
/* close uarts */
|
/* close uarts */
|
||||||
close(ardrone_write);
|
close(ardrone_write);
|
||||||
//ar_multiplexing_deinit(gpios);
|
|
||||||
|
|
||||||
/* enable UART, writes potentially an empty buffer, but multiplexing is disabled */
|
/* enable UART, writes potentially an empty buffer, but multiplexing is disabled */
|
||||||
ardrone_write = ardrone_open_uart(device, &uart_config_original);
|
ardrone_write = ardrone_open_uart(device, &uart_config_original);
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ CSRCS = attitude_estimator_ekf_main.c \
|
|||||||
codegen/eye.c \
|
codegen/eye.c \
|
||||||
codegen/attitudeKalmanfilter.c \
|
codegen/attitudeKalmanfilter.c \
|
||||||
codegen/mrdivide.c \
|
codegen/mrdivide.c \
|
||||||
|
codegen/rdivide.c \
|
||||||
codegen/attitudeKalmanfilter_initialize.c \
|
codegen/attitudeKalmanfilter_initialize.c \
|
||||||
codegen/attitudeKalmanfilter_terminate.c \
|
codegen/attitudeKalmanfilter_terminate.c \
|
||||||
codegen/rt_nonfinite.c \
|
codegen/rt_nonfinite.c \
|
||||||
@@ -47,8 +48,9 @@ CSRCS = attitude_estimator_ekf_main.c \
|
|||||||
codegen/rtGetNaN.c \
|
codegen/rtGetNaN.c \
|
||||||
codegen/norm.c \
|
codegen/norm.c \
|
||||||
codegen/diag.c \
|
codegen/diag.c \
|
||||||
codegen/cross.c \
|
codegen/power.c \
|
||||||
codegen/power.c
|
codegen/cross.c
|
||||||
|
|
||||||
|
|
||||||
# XXX this is *horribly* broken
|
# XXX this is *horribly* broken
|
||||||
INCLUDES += $(TOPDIR)/../mavlink/include/mavlink
|
INCLUDES += $(TOPDIR)/../mavlink/include/mavlink
|
||||||
|
|||||||
Executable → Regular
Executable → Regular
@@ -71,46 +71,34 @@ __EXPORT int attitude_estimator_ekf_main(int argc, char *argv[]);
|
|||||||
|
|
||||||
static unsigned int loop_interval_alarm = 6500; // loop interval in microseconds
|
static unsigned int loop_interval_alarm = 6500; // loop interval in microseconds
|
||||||
|
|
||||||
static float dt = 1.0f;
|
static float dt = 0.005f;
|
||||||
/* state vector x has the following entries [ax,ay,az||mx,my,mz||wox,woy,woz||wx,wy,wz]' */
|
/* state vector x has the following entries [ax,ay,az||mx,my,mz||wox,woy,woz||wx,wy,wz]' */
|
||||||
static float z_k[9]; /**< Measurement vector */
|
static float z_k[9] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 9.81f, 0.2f, -0.2f, 0.2f}; /**< Measurement vector */
|
||||||
static float x_aposteriori_k[12]; /**< */
|
static float x_aposteriori_k[12]; /**< states */
|
||||||
static float x_aposteriori[12];
|
|
||||||
static float P_aposteriori_k[144] = {100.f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
static float P_aposteriori_k[144] = {100.f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 100.f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 100.f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 100.f, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 100.f, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 100.f, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 100.f, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 100.f, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 100.f, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 100.f, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 100.f, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 100.f, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 100.f, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 100.f, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 100.f, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 100.f, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 100.f, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 100.0f, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 100.0f, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0, 100.0f, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0, 100.0f, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0, 0, 100.0f,
|
0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0, 0, 100.0f,
|
||||||
};
|
}; /**< init: diagonal matrix with big values */
|
||||||
|
|
||||||
static float P_aposteriori[144] = {100.f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
static float x_aposteriori[12];
|
||||||
0, 100.f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
static float P_aposteriori[144];
|
||||||
0, 0, 100.f, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 100.f, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 100.f, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 100.f, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 100.f, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 100.f, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 100.f, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 100.0f, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0, 100.0f, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0.0f, 0, 0, 100.0f,
|
|
||||||
}; /**< init: diagonal matrix with big values */
|
|
||||||
|
|
||||||
/* output euler angles */
|
/* output euler angles */
|
||||||
static float euler[3] = {0.0f, 0.0f, 0.0f};
|
static float euler[3] = {0.0f, 0.0f, 0.0f};
|
||||||
|
|
||||||
static float Rot_matrix[9] = {1.f, 0, 0,
|
static float Rot_matrix[9] = {1.f, 0, 0,
|
||||||
0, 1.f, 0,
|
0, 1.f, 0,
|
||||||
0, 0, 1.f
|
0, 0, 1.f
|
||||||
}; /**< init: identity matrix */
|
}; /**< init: identity matrix */
|
||||||
|
|
||||||
|
|
||||||
static bool thread_should_exit = false; /**< Deamon exit flag */
|
static bool thread_should_exit = false; /**< Deamon exit flag */
|
||||||
@@ -159,11 +147,11 @@ int attitude_estimator_ekf_main(int argc, char *argv[])
|
|||||||
|
|
||||||
thread_should_exit = false;
|
thread_should_exit = false;
|
||||||
attitude_estimator_ekf_task = task_spawn("attitude_estimator_ekf",
|
attitude_estimator_ekf_task = task_spawn("attitude_estimator_ekf",
|
||||||
SCHED_DEFAULT,
|
SCHED_DEFAULT,
|
||||||
SCHED_PRIORITY_MAX - 5,
|
SCHED_PRIORITY_MAX - 5,
|
||||||
20000,
|
20000,
|
||||||
attitude_estimator_ekf_thread_main,
|
attitude_estimator_ekf_thread_main,
|
||||||
(argv) ? (const char **)&argv[2] : (const char **)NULL);
|
(argv) ? (const char **)&argv[2] : (const char **)NULL);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +224,7 @@ int attitude_estimator_ekf_thread_main(int argc, char *argv[])
|
|||||||
|
|
||||||
/* advertise debug value */
|
/* advertise debug value */
|
||||||
struct debug_key_value_s dbg = { .key = "", .value = 0.0f };
|
struct debug_key_value_s dbg = { .key = "", .value = 0.0f };
|
||||||
orb_advert_t pub_dbg = orb_advertise(ORB_ID(debug_key_value), &dbg);
|
orb_advert_t pub_dbg = -1;
|
||||||
|
|
||||||
/* keep track of sensor updates */
|
/* keep track of sensor updates */
|
||||||
uint32_t sensor_last_count[3] = {0, 0, 0};
|
uint32_t sensor_last_count[3] = {0, 0, 0};
|
||||||
@@ -250,12 +238,18 @@ int attitude_estimator_ekf_thread_main(int argc, char *argv[])
|
|||||||
/* initialize parameter handles */
|
/* initialize parameter handles */
|
||||||
parameters_init(&ekf_param_handles);
|
parameters_init(&ekf_param_handles);
|
||||||
|
|
||||||
|
uint64_t start_time = hrt_absolute_time();
|
||||||
|
bool initialized = false;
|
||||||
|
|
||||||
|
float gyro_offsets[3] = { 0.0f, 0.0f, 0.0f };
|
||||||
|
unsigned offset_count = 0;
|
||||||
|
|
||||||
/* Main loop*/
|
/* Main loop*/
|
||||||
while (!thread_should_exit) {
|
while (!thread_should_exit) {
|
||||||
|
|
||||||
struct pollfd fds[2] = {
|
struct pollfd fds[2] = {
|
||||||
{ .fd = sub_raw, .events = POLLIN },
|
{ .fd = sub_raw, .events = POLLIN },
|
||||||
{ .fd = sub_params, .events = POLLIN }
|
{ .fd = sub_params, .events = POLLIN }
|
||||||
};
|
};
|
||||||
int ret = poll(fds, 2, 1000);
|
int ret = poll(fds, 2, 1000);
|
||||||
|
|
||||||
@@ -265,7 +259,7 @@ int attitude_estimator_ekf_thread_main(int argc, char *argv[])
|
|||||||
/* XXX this means no sensor data - should be critical or emergency */
|
/* XXX this means no sensor data - should be critical or emergency */
|
||||||
printf("[attitude estimator ekf] WARNING: Not getting sensor data - sensor app running?\n");
|
printf("[attitude estimator ekf] WARNING: Not getting sensor data - sensor app running?\n");
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* only update parameters if they changed */
|
/* only update parameters if they changed */
|
||||||
if (fds[1].revents & POLLIN) {
|
if (fds[1].revents & POLLIN) {
|
||||||
/* read from param to clear updated flag */
|
/* read from param to clear updated flag */
|
||||||
@@ -282,156 +276,178 @@ int attitude_estimator_ekf_thread_main(int argc, char *argv[])
|
|||||||
/* get latest measurements */
|
/* get latest measurements */
|
||||||
orb_copy(ORB_ID(sensor_combined), sub_raw, &raw);
|
orb_copy(ORB_ID(sensor_combined), sub_raw, &raw);
|
||||||
|
|
||||||
/* Calculate data time difference in seconds */
|
if (!initialized) {
|
||||||
dt = (raw.timestamp - last_measurement) / 1000000.0f;
|
|
||||||
last_measurement = raw.timestamp;
|
|
||||||
uint8_t update_vect[3] = {0, 0, 0};
|
|
||||||
|
|
||||||
/* Fill in gyro measurements */
|
gyro_offsets[0] += raw.gyro_rad_s[0];
|
||||||
if (sensor_last_count[0] != raw.gyro_counter) {
|
gyro_offsets[1] += raw.gyro_rad_s[1];
|
||||||
update_vect[0] = 1;
|
gyro_offsets[2] += raw.gyro_rad_s[2];
|
||||||
sensor_last_count[0] = raw.gyro_counter;
|
offset_count++;
|
||||||
sensor_update_hz[0] = 1e6f / (raw.timestamp - sensor_last_timestamp[0]);
|
|
||||||
sensor_last_timestamp[0] = raw.timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
z_k[0] = raw.gyro_rad_s[0];
|
if (hrt_absolute_time() - start_time > 3000000LL) {
|
||||||
z_k[1] = raw.gyro_rad_s[1];
|
initialized = true;
|
||||||
z_k[2] = raw.gyro_rad_s[2];
|
gyro_offsets[0] /= offset_count;
|
||||||
|
gyro_offsets[1] /= offset_count;
|
||||||
|
gyro_offsets[2] /= offset_count;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
/* update accelerometer measurements */
|
/* Calculate data time difference in seconds */
|
||||||
if (sensor_last_count[1] != raw.accelerometer_counter) {
|
dt = (raw.timestamp - last_measurement) / 1000000.0f;
|
||||||
update_vect[1] = 1;
|
last_measurement = raw.timestamp;
|
||||||
sensor_last_count[1] = raw.accelerometer_counter;
|
uint8_t update_vect[3] = {0, 0, 0};
|
||||||
sensor_update_hz[1] = 1e6f / (raw.timestamp - sensor_last_timestamp[1]);
|
|
||||||
sensor_last_timestamp[1] = raw.timestamp;
|
|
||||||
}
|
|
||||||
z_k[3] = raw.accelerometer_m_s2[0];
|
|
||||||
z_k[4] = raw.accelerometer_m_s2[1];
|
|
||||||
z_k[5] = raw.accelerometer_m_s2[2];
|
|
||||||
|
|
||||||
/* update magnetometer measurements */
|
/* Fill in gyro measurements */
|
||||||
if (sensor_last_count[2] != raw.magnetometer_counter) {
|
if (sensor_last_count[0] != raw.gyro_counter) {
|
||||||
update_vect[2] = 1;
|
update_vect[0] = 1;
|
||||||
sensor_last_count[2] = raw.magnetometer_counter;
|
sensor_last_count[0] = raw.gyro_counter;
|
||||||
sensor_update_hz[2] = 1e6f / (raw.timestamp - sensor_last_timestamp[2]);
|
sensor_update_hz[0] = 1e6f / (raw.timestamp - sensor_last_timestamp[0]);
|
||||||
sensor_last_timestamp[2] = raw.timestamp;
|
sensor_last_timestamp[0] = raw.timestamp;
|
||||||
}
|
}
|
||||||
z_k[6] = raw.magnetometer_ga[0];
|
|
||||||
z_k[7] = raw.magnetometer_ga[1];
|
|
||||||
z_k[8] = raw.magnetometer_ga[2];
|
|
||||||
|
|
||||||
uint64_t now = hrt_absolute_time();
|
z_k[0] = raw.gyro_rad_s[0] - gyro_offsets[0];
|
||||||
unsigned int time_elapsed = now - last_run;
|
z_k[1] = raw.gyro_rad_s[1] - gyro_offsets[1];
|
||||||
last_run = now;
|
z_k[2] = raw.gyro_rad_s[2] - gyro_offsets[2];
|
||||||
|
|
||||||
if (time_elapsed > loop_interval_alarm) {
|
/* update accelerometer measurements */
|
||||||
//TODO: add warning, cpu overload here
|
if (sensor_last_count[1] != raw.accelerometer_counter) {
|
||||||
// if (overloadcounter == 20) {
|
update_vect[1] = 1;
|
||||||
// printf("CPU OVERLOAD DETECTED IN ATTITUDE ESTIMATOR EKF (%lu > %lu)\n", time_elapsed, loop_interval_alarm);
|
sensor_last_count[1] = raw.accelerometer_counter;
|
||||||
// overloadcounter = 0;
|
sensor_update_hz[1] = 1e6f / (raw.timestamp - sensor_last_timestamp[1]);
|
||||||
|
sensor_last_timestamp[1] = raw.timestamp;
|
||||||
|
}
|
||||||
|
z_k[3] = raw.accelerometer_m_s2[0];
|
||||||
|
z_k[4] = raw.accelerometer_m_s2[1];
|
||||||
|
z_k[5] = raw.accelerometer_m_s2[2];
|
||||||
|
|
||||||
|
/* update magnetometer measurements */
|
||||||
|
if (sensor_last_count[2] != raw.magnetometer_counter) {
|
||||||
|
update_vect[2] = 1;
|
||||||
|
sensor_last_count[2] = raw.magnetometer_counter;
|
||||||
|
sensor_update_hz[2] = 1e6f / (raw.timestamp - sensor_last_timestamp[2]);
|
||||||
|
sensor_last_timestamp[2] = raw.timestamp;
|
||||||
|
}
|
||||||
|
z_k[6] = raw.magnetometer_ga[0];
|
||||||
|
z_k[7] = raw.magnetometer_ga[1];
|
||||||
|
z_k[8] = raw.magnetometer_ga[2];
|
||||||
|
|
||||||
|
uint64_t now = hrt_absolute_time();
|
||||||
|
unsigned int time_elapsed = now - last_run;
|
||||||
|
last_run = now;
|
||||||
|
|
||||||
|
if (time_elapsed > loop_interval_alarm) {
|
||||||
|
//TODO: add warning, cpu overload here
|
||||||
|
// if (overloadcounter == 20) {
|
||||||
|
// printf("CPU OVERLOAD DETECTED IN ATTITUDE ESTIMATOR EKF (%lu > %lu)\n", time_elapsed, loop_interval_alarm);
|
||||||
|
// overloadcounter = 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
overloadcounter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t z_k_sizes = 9;
|
||||||
|
// float u[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
|
|
||||||
|
static bool const_initialized = false;
|
||||||
|
|
||||||
|
/* initialize with good values once we have a reasonable dt estimate */
|
||||||
|
if (!const_initialized && dt < 0.05 && dt > 0.005)
|
||||||
|
{
|
||||||
|
dt = 0.005f;
|
||||||
|
parameters_update(&ekf_param_handles, &ekf_params);
|
||||||
|
|
||||||
|
x_aposteriori_k[0] = z_k[0];
|
||||||
|
x_aposteriori_k[1] = z_k[1];
|
||||||
|
x_aposteriori_k[2] = z_k[2];
|
||||||
|
x_aposteriori_k[3] = 0.0f;
|
||||||
|
x_aposteriori_k[4] = 0.0f;
|
||||||
|
x_aposteriori_k[5] = 0.0f;
|
||||||
|
x_aposteriori_k[6] = z_k[3];
|
||||||
|
x_aposteriori_k[7] = z_k[4];
|
||||||
|
x_aposteriori_k[8] = z_k[5];
|
||||||
|
x_aposteriori_k[9] = z_k[6];
|
||||||
|
x_aposteriori_k[10] = z_k[7];
|
||||||
|
x_aposteriori_k[11] = z_k[8];
|
||||||
|
|
||||||
|
const_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do not execute the filter if not initialized */
|
||||||
|
if (!const_initialized) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t timing_start = hrt_absolute_time();
|
||||||
|
|
||||||
|
attitudeKalmanfilter(update_vect, dt, z_k, x_aposteriori_k, P_aposteriori_k, ekf_params.q, ekf_params.r,
|
||||||
|
euler, Rot_matrix, x_aposteriori, P_aposteriori);
|
||||||
|
/* swap values for next iteration, check for fatal inputs */
|
||||||
|
if (isfinite(euler[0]) && isfinite(euler[1]) && isfinite(euler[2])) {
|
||||||
|
memcpy(P_aposteriori_k, P_aposteriori, sizeof(P_aposteriori_k));
|
||||||
|
memcpy(x_aposteriori_k, x_aposteriori, sizeof(x_aposteriori_k));
|
||||||
|
} else {
|
||||||
|
/* due to inputs or numerical failure the output is invalid, skip it */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t timing_diff = hrt_absolute_time() - timing_start;
|
||||||
|
|
||||||
|
// /* print rotation matrix every 200th time */
|
||||||
|
if (printcounter % 200 == 0) {
|
||||||
|
// printf("x apo:\n%8.4f\t%8.4f\t%8.4f\n%8.4f\t%8.4f\t%8.4f\n%8.4f\t%8.4f\t%8.4f\n",
|
||||||
|
// x_aposteriori[0], x_aposteriori[1], x_aposteriori[2],
|
||||||
|
// x_aposteriori[3], x_aposteriori[4], x_aposteriori[5],
|
||||||
|
// x_aposteriori[6], x_aposteriori[7], x_aposteriori[8]);
|
||||||
|
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
//printf("EKF attitude iteration: %d, runtime: %d us, dt: %d us (%d Hz)\n", loopcounter, (int)timing_diff, (int)(dt * 1000000.0f), (int)(1.0f / dt));
|
||||||
|
//printf("roll: %8.4f\tpitch: %8.4f\tyaw:%8.4f\n", (double)euler[0], (double)euler[1], (double)euler[2]);
|
||||||
|
//printf("update rates gyro: %8.4f\taccel: %8.4f\tmag:%8.4f\n", (double)sensor_update_hz[0], (double)sensor_update_hz[1], (double)sensor_update_hz[2]);
|
||||||
|
// printf("\n%d\t%d\t%d\n%d\t%d\t%d\n%d\t%d\t%d\n", (int)(Rot_matrix[0] * 100), (int)(Rot_matrix[1] * 100), (int)(Rot_matrix[2] * 100),
|
||||||
|
// (int)(Rot_matrix[3] * 100), (int)(Rot_matrix[4] * 100), (int)(Rot_matrix[5] * 100),
|
||||||
|
// (int)(Rot_matrix[6] * 100), (int)(Rot_matrix[7] * 100), (int)(Rot_matrix[8] * 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
// int i = printcounter % 9;
|
||||||
|
|
||||||
|
// // for (int i = 0; i < 9; i++) {
|
||||||
|
// char name[10];
|
||||||
|
// sprintf(name, "xapo #%d", i);
|
||||||
|
// memcpy(dbg.key, name, sizeof(dbg.key));
|
||||||
|
// dbg.value = x_aposteriori[i];
|
||||||
|
// if (pub_dbg < 0) {
|
||||||
|
// pub_dbg = orb_advertise(ORB_ID(debug_key_value), &dbg);
|
||||||
|
// } else {
|
||||||
|
// orb_publish(ORB_ID(debug_key_value), pub_dbg, &dbg);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
overloadcounter++;
|
printcounter++;
|
||||||
|
|
||||||
|
if (last_data > 0 && raw.timestamp - last_data > 12000) printf("[attitude estimator ekf] sensor data missed! (%llu)\n", raw.timestamp - last_data);
|
||||||
|
|
||||||
|
last_data = raw.timestamp;
|
||||||
|
|
||||||
|
/* send out */
|
||||||
|
att.timestamp = raw.timestamp;
|
||||||
|
att.roll = euler[0];
|
||||||
|
att.pitch = euler[1];
|
||||||
|
att.yaw = euler[2];
|
||||||
|
|
||||||
|
att.rollspeed = x_aposteriori[0];
|
||||||
|
att.pitchspeed = x_aposteriori[1];
|
||||||
|
att.yawspeed = x_aposteriori[2];
|
||||||
|
//att.yawspeed =z_k[2] ;
|
||||||
|
/* copy offsets */
|
||||||
|
memcpy(&att.rate_offsets, &(x_aposteriori[3]), sizeof(att.rate_offsets));
|
||||||
|
|
||||||
|
/* copy rotation matrix */
|
||||||
|
memcpy(&att.R, Rot_matrix, sizeof(Rot_matrix));
|
||||||
|
att.R_valid = true;
|
||||||
|
|
||||||
|
// Broadcast
|
||||||
|
orb_publish(ORB_ID(vehicle_attitude), pub_att, &att);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t z_k_sizes = 9;
|
|
||||||
// float u[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
|
||||||
|
|
||||||
static bool const_initialized = false;
|
|
||||||
|
|
||||||
/* initialize with good values once we have a reasonable dt estimate */
|
|
||||||
if (!const_initialized /*&& dt < 0.05 && dt > 0.005*/)
|
|
||||||
{
|
|
||||||
dt = 0.005f;
|
|
||||||
parameters_update(&ekf_param_handles, &ekf_params);
|
|
||||||
|
|
||||||
x_aposteriori_k[0] = z_k[0];
|
|
||||||
x_aposteriori_k[1] = z_k[1];
|
|
||||||
x_aposteriori_k[2] = z_k[2];
|
|
||||||
x_aposteriori_k[3] = 0.0f;
|
|
||||||
x_aposteriori_k[4] = 0.0f;
|
|
||||||
x_aposteriori_k[5] = 0.0f;
|
|
||||||
x_aposteriori_k[6] = z_k[3];
|
|
||||||
x_aposteriori_k[7] = z_k[4];
|
|
||||||
x_aposteriori_k[8] = z_k[5];
|
|
||||||
x_aposteriori_k[9] = z_k[6];
|
|
||||||
x_aposteriori_k[10] = z_k[7];
|
|
||||||
x_aposteriori_k[11] = z_k[8];
|
|
||||||
|
|
||||||
const_initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* do not execute the filter if not initialized */
|
|
||||||
if (!const_initialized) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
dt = 0.004f;
|
|
||||||
|
|
||||||
uint64_t timing_start = hrt_absolute_time();
|
|
||||||
// attitudeKalmanfilter(dt, update_vect, z_k, &z_k_sizes, u, x_aposteriori_k, P_aposteriori_k, knownConst, euler,
|
|
||||||
// Rot_matrix, x_aposteriori, P_aposteriori);
|
|
||||||
attitudeKalmanfilter(update_vect, dt, z_k, x_aposteriori_k, P_aposteriori_k, ekf_params.q, ekf_params.r,
|
|
||||||
euler, Rot_matrix, x_aposteriori, P_aposteriori);
|
|
||||||
/* swap values for next iteration */
|
|
||||||
memcpy(P_aposteriori_k, P_aposteriori, sizeof(P_aposteriori_k));
|
|
||||||
memcpy(x_aposteriori_k, x_aposteriori, sizeof(x_aposteriori_k));
|
|
||||||
uint64_t timing_diff = hrt_absolute_time() - timing_start;
|
|
||||||
|
|
||||||
// /* print rotation matrix every 200th time */
|
|
||||||
if (printcounter % 200 == 0) {
|
|
||||||
// printf("x apo:\n%8.4f\t%8.4f\t%8.4f\n%8.4f\t%8.4f\t%8.4f\n%8.4f\t%8.4f\t%8.4f\n",
|
|
||||||
// x_aposteriori[0], x_aposteriori[1], x_aposteriori[2],
|
|
||||||
// x_aposteriori[3], x_aposteriori[4], x_aposteriori[5],
|
|
||||||
// x_aposteriori[6], x_aposteriori[7], x_aposteriori[8]);
|
|
||||||
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
//printf("EKF attitude iteration: %d, runtime: %d us, dt: %d us (%d Hz)\n", loopcounter, (int)timing_diff, (int)(dt * 1000000.0f), (int)(1.0f / dt));
|
|
||||||
//printf("roll: %8.4f\tpitch: %8.4f\tyaw:%8.4f\n", (double)euler[0], (double)euler[1], (double)euler[2]);
|
|
||||||
//printf("update rates gyro: %8.4f\taccel: %8.4f\tmag:%8.4f\n", (double)sensor_update_hz[0], (double)sensor_update_hz[1], (double)sensor_update_hz[2]);
|
|
||||||
// printf("\n%d\t%d\t%d\n%d\t%d\t%d\n%d\t%d\t%d\n", (int)(Rot_matrix[0] * 100), (int)(Rot_matrix[1] * 100), (int)(Rot_matrix[2] * 100),
|
|
||||||
// (int)(Rot_matrix[3] * 100), (int)(Rot_matrix[4] * 100), (int)(Rot_matrix[5] * 100),
|
|
||||||
// (int)(Rot_matrix[6] * 100), (int)(Rot_matrix[7] * 100), (int)(Rot_matrix[8] * 100));
|
|
||||||
}
|
|
||||||
|
|
||||||
// int i = printcounter % 9;
|
|
||||||
|
|
||||||
// // for (int i = 0; i < 9; i++) {
|
|
||||||
// char name[10];
|
|
||||||
// sprintf(name, "xapo #%d", i);
|
|
||||||
// memcpy(dbg.key, name, sizeof(dbg.key));
|
|
||||||
// dbg.value = x_aposteriori[i];
|
|
||||||
// orb_publish(ORB_ID(debug_key_value), pub_dbg, &dbg);
|
|
||||||
|
|
||||||
printcounter++;
|
|
||||||
|
|
||||||
if (last_data > 0 && raw.timestamp - last_data > 12000) printf("[attitude estimator ekf] sensor data missed! (%llu)\n", raw.timestamp - last_data);
|
|
||||||
|
|
||||||
last_data = raw.timestamp;
|
|
||||||
|
|
||||||
/* send out */
|
|
||||||
att.timestamp = raw.timestamp;
|
|
||||||
att.roll = euler[0];
|
|
||||||
att.pitch = euler[1];
|
|
||||||
att.yaw = euler[2];
|
|
||||||
|
|
||||||
// XXX replace with x_apo after fix to filter
|
|
||||||
att.rollspeed = raw.gyro_rad_s[0]; //x_aposteriori[0];
|
|
||||||
att.pitchspeed = raw.gyro_rad_s[1]; //x_aposteriori[1];
|
|
||||||
att.yawspeed = raw.gyro_rad_s[2]; //x_aposteriori[2];
|
|
||||||
|
|
||||||
/* copy offsets */
|
|
||||||
memcpy(&att.rate_offsets, &(x_aposteriori[3]), sizeof(att.rate_offsets));
|
|
||||||
|
|
||||||
/* copy rotation matrix */
|
|
||||||
memcpy(&att.R, Rot_matrix, sizeof(Rot_matrix));
|
|
||||||
att.R_valid = true;
|
|
||||||
|
|
||||||
// Broadcast
|
|
||||||
orb_publish(ORB_ID(vehicle_attitude), pub_att, &att);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,13 +61,13 @@ PARAM_DEFINE_FLOAT(EKF_ATT_Q10, 1e-1f);
|
|||||||
PARAM_DEFINE_FLOAT(EKF_ATT_Q11, 1e-1f);
|
PARAM_DEFINE_FLOAT(EKF_ATT_Q11, 1e-1f);
|
||||||
|
|
||||||
/* gyro measurement noise */
|
/* gyro measurement noise */
|
||||||
PARAM_DEFINE_FLOAT(EKF_ATT_R0, 1e-2f);
|
PARAM_DEFINE_FLOAT(EKF_ATT_R0, 0.01f);
|
||||||
PARAM_DEFINE_FLOAT(EKF_ATT_R1, 1e-2f);
|
PARAM_DEFINE_FLOAT(EKF_ATT_R1, 0.01f);
|
||||||
PARAM_DEFINE_FLOAT(EKF_ATT_R2, 1e-2f);
|
PARAM_DEFINE_FLOAT(EKF_ATT_R2, 0.01f);
|
||||||
/* accelerometer measurement noise */
|
/* accelerometer measurement noise */
|
||||||
PARAM_DEFINE_FLOAT(EKF_ATT_R3, 1e-1f);
|
PARAM_DEFINE_FLOAT(EKF_ATT_R3, 1e1f);
|
||||||
PARAM_DEFINE_FLOAT(EKF_ATT_R4, 1e-1f);
|
PARAM_DEFINE_FLOAT(EKF_ATT_R4, 1e1f);
|
||||||
PARAM_DEFINE_FLOAT(EKF_ATT_R5, 1e-1f);
|
PARAM_DEFINE_FLOAT(EKF_ATT_R5, 1e1f);
|
||||||
/* magnetometer measurement noise */
|
/* magnetometer measurement noise */
|
||||||
PARAM_DEFINE_FLOAT(EKF_ATT_R6, 1e-1f);
|
PARAM_DEFINE_FLOAT(EKF_ATT_R6, 1e-1f);
|
||||||
PARAM_DEFINE_FLOAT(EKF_ATT_R7, 1e-1f);
|
PARAM_DEFINE_FLOAT(EKF_ATT_R7, 1e-1f);
|
||||||
|
|||||||
Executable → Regular
+219
-181
File diff suppressed because it is too large
Load Diff
Executable → Regular
+2
-2
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'attitudeKalmanfilter'
|
* Code generation for function 'attitudeKalmanfilter'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
#define __ATTITUDEKALMANFILTER_H__
|
#define __ATTITUDEKALMANFILTER_H__
|
||||||
/* Include files */
|
/* Include files */
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "rt_defines.h"
|
#include "rt_defines.h"
|
||||||
|
|||||||
Executable → Regular
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'attitudeKalmanfilter_initialize'
|
* Code generation for function 'attitudeKalmanfilter_initialize'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
Executable → Regular
+2
-2
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'attitudeKalmanfilter_initialize'
|
* Code generation for function 'attitudeKalmanfilter_initialize'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
#define __ATTITUDEKALMANFILTER_INITIALIZE_H__
|
#define __ATTITUDEKALMANFILTER_INITIALIZE_H__
|
||||||
/* Include files */
|
/* Include files */
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "rt_defines.h"
|
#include "rt_defines.h"
|
||||||
|
|||||||
Executable → Regular
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'attitudeKalmanfilter_terminate'
|
* Code generation for function 'attitudeKalmanfilter_terminate'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
Executable → Regular
+2
-2
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'attitudeKalmanfilter_terminate'
|
* Code generation for function 'attitudeKalmanfilter_terminate'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
#define __ATTITUDEKALMANFILTER_TERMINATE_H__
|
#define __ATTITUDEKALMANFILTER_TERMINATE_H__
|
||||||
/* Include files */
|
/* Include files */
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "rt_defines.h"
|
#include "rt_defines.h"
|
||||||
|
|||||||
Executable → Regular
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'attitudeKalmanfilter'
|
* Code generation for function 'attitudeKalmanfilter'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
Executable → Regular
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'cross'
|
* Code generation for function 'cross'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
Executable → Regular
+2
-2
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'cross'
|
* Code generation for function 'cross'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
#define __CROSS_H__
|
#define __CROSS_H__
|
||||||
/* Include files */
|
/* Include files */
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "rt_defines.h"
|
#include "rt_defines.h"
|
||||||
|
|||||||
Executable → Regular
+4
-4
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'diag'
|
* Code generation for function 'diag'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
void b_diag(const real32_T v[9], real32_T d[81])
|
void b_diag(const real32_T v[9], real32_T d[81])
|
||||||
{
|
{
|
||||||
int32_T j;
|
int32_T j;
|
||||||
memset((void *)&d[0], 0, 81U * sizeof(real32_T));
|
memset(&d[0], 0, 81U * sizeof(real32_T));
|
||||||
for (j = 0; j < 9; j++) {
|
for (j = 0; j < 9; j++) {
|
||||||
d[j + 9 * j] = v[j];
|
d[j + 9 * j] = v[j];
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,7 @@ void c_diag(const real32_T v[3], real32_T d[9])
|
|||||||
void d_diag(const real32_T v[6], real32_T d[36])
|
void d_diag(const real32_T v[6], real32_T d[36])
|
||||||
{
|
{
|
||||||
int32_T j;
|
int32_T j;
|
||||||
memset((void *)&d[0], 0, 36U * sizeof(real32_T));
|
memset(&d[0], 0, 36U * sizeof(real32_T));
|
||||||
for (j = 0; j < 6; j++) {
|
for (j = 0; j < 6; j++) {
|
||||||
d[j + 6 * j] = v[j];
|
d[j + 6 * j] = v[j];
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,7 @@ void d_diag(const real32_T v[6], real32_T d[36])
|
|||||||
void diag(const real32_T v[12], real32_T d[144])
|
void diag(const real32_T v[12], real32_T d[144])
|
||||||
{
|
{
|
||||||
int32_T j;
|
int32_T j;
|
||||||
memset((void *)&d[0], 0, 144U * sizeof(real32_T));
|
memset(&d[0], 0, 144U * sizeof(real32_T));
|
||||||
for (j = 0; j < 12; j++) {
|
for (j = 0; j < 12; j++) {
|
||||||
d[j + 12 * j] = v[j];
|
d[j + 12 * j] = v[j];
|
||||||
}
|
}
|
||||||
|
|||||||
Executable → Regular
+2
-2
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'diag'
|
* Code generation for function 'diag'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
#define __DIAG_H__
|
#define __DIAG_H__
|
||||||
/* Include files */
|
/* Include files */
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "rt_defines.h"
|
#include "rt_defines.h"
|
||||||
|
|||||||
Executable → Regular
+3
-3
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'eye'
|
* Code generation for function 'eye'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
void b_eye(real_T I[144])
|
void b_eye(real_T I[144])
|
||||||
{
|
{
|
||||||
int32_T i;
|
int32_T i;
|
||||||
memset((void *)&I[0], 0, 144U * sizeof(real_T));
|
memset(&I[0], 0, 144U * sizeof(real_T));
|
||||||
for (i = 0; i < 12; i++) {
|
for (i = 0; i < 12; i++) {
|
||||||
I[i + 12 * i] = 1.0;
|
I[i + 12 * i] = 1.0;
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,7 @@ void b_eye(real_T I[144])
|
|||||||
void eye(real_T I[9])
|
void eye(real_T I[9])
|
||||||
{
|
{
|
||||||
int32_T i;
|
int32_T i;
|
||||||
memset((void *)&I[0], 0, 9U * sizeof(real_T));
|
memset(&I[0], 0, 9U * sizeof(real_T));
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
I[i + 3 * i] = 1.0;
|
I[i + 3 * i] = 1.0;
|
||||||
}
|
}
|
||||||
|
|||||||
Executable → Regular
+2
-2
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'eye'
|
* Code generation for function 'eye'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
#define __EYE_H__
|
#define __EYE_H__
|
||||||
/* Include files */
|
/* Include files */
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "rt_defines.h"
|
#include "rt_defines.h"
|
||||||
|
|||||||
Executable → Regular
+104
-114
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'mrdivide'
|
* Code generation for function 'mrdivide'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -29,9 +29,9 @@
|
|||||||
*/
|
*/
|
||||||
void b_mrdivide(const real32_T A[36], const real32_T B[9], real32_T y[36])
|
void b_mrdivide(const real32_T A[36], const real32_T B[9], real32_T y[36])
|
||||||
{
|
{
|
||||||
|
real32_T b_A[9];
|
||||||
int32_T rtemp;
|
int32_T rtemp;
|
||||||
int32_T k;
|
int32_T k;
|
||||||
real32_T b_A[9];
|
|
||||||
real32_T b_B[36];
|
real32_T b_B[36];
|
||||||
int32_T r1;
|
int32_T r1;
|
||||||
int32_T r2;
|
int32_T r2;
|
||||||
@@ -54,15 +54,15 @@ void b_mrdivide(const real32_T A[36], const real32_T B[9], real32_T y[36])
|
|||||||
r1 = 0;
|
r1 = 0;
|
||||||
r2 = 1;
|
r2 = 1;
|
||||||
r3 = 2;
|
r3 = 2;
|
||||||
maxval = (real32_T)fabsf(b_A[0]);
|
maxval = (real32_T)fabs(b_A[0]);
|
||||||
a21 = (real32_T)fabsf(b_A[1]);
|
a21 = (real32_T)fabs(b_A[1]);
|
||||||
if (a21 > maxval) {
|
if (a21 > maxval) {
|
||||||
maxval = a21;
|
maxval = a21;
|
||||||
r1 = 1;
|
r1 = 1;
|
||||||
r2 = 0;
|
r2 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((real32_T)fabsf(b_A[2]) > maxval) {
|
if ((real32_T)fabs(b_A[2]) > maxval) {
|
||||||
r1 = 2;
|
r1 = 2;
|
||||||
r2 = 1;
|
r2 = 1;
|
||||||
r3 = 0;
|
r3 = 0;
|
||||||
@@ -74,7 +74,7 @@ void b_mrdivide(const real32_T A[36], const real32_T B[9], real32_T y[36])
|
|||||||
b_A[3 + r3] -= b_A[r3] * b_A[3 + r1];
|
b_A[3 + r3] -= b_A[r3] * b_A[3 + r1];
|
||||||
b_A[6 + r2] -= b_A[r2] * b_A[6 + r1];
|
b_A[6 + r2] -= b_A[r2] * b_A[6 + r1];
|
||||||
b_A[6 + r3] -= b_A[r3] * b_A[6 + r1];
|
b_A[6 + r3] -= b_A[r3] * b_A[6 + r1];
|
||||||
if ((real32_T)fabsf(b_A[3 + r3]) > (real32_T)fabsf(b_A[3 + r2])) {
|
if ((real32_T)fabs(b_A[3 + r3]) > (real32_T)fabs(b_A[3 + r2])) {
|
||||||
rtemp = r2;
|
rtemp = r2;
|
||||||
r2 = r3;
|
r2 = r3;
|
||||||
r3 = rtemp;
|
r3 = rtemp;
|
||||||
@@ -107,51 +107,46 @@ void b_mrdivide(const real32_T A[36], const real32_T B[9], real32_T y[36])
|
|||||||
*/
|
*/
|
||||||
void c_mrdivide(const real32_T A[72], const real32_T B[36], real32_T y[72])
|
void c_mrdivide(const real32_T A[72], const real32_T B[36], real32_T y[72])
|
||||||
{
|
{
|
||||||
int32_T jy;
|
|
||||||
int32_T iy;
|
|
||||||
real32_T b_A[36];
|
real32_T b_A[36];
|
||||||
int8_T ipiv[6];
|
int8_T ipiv[6];
|
||||||
|
int32_T i3;
|
||||||
|
int32_T iy;
|
||||||
int32_T j;
|
int32_T j;
|
||||||
int32_T mmj;
|
|
||||||
int32_T jj;
|
|
||||||
int32_T jp1j;
|
|
||||||
int32_T c;
|
int32_T c;
|
||||||
int32_T ix;
|
int32_T ix;
|
||||||
real32_T temp;
|
real32_T temp;
|
||||||
int32_T k;
|
int32_T k;
|
||||||
real32_T s;
|
real32_T s;
|
||||||
int32_T loop_ub;
|
int32_T jy;
|
||||||
|
int32_T ijA;
|
||||||
real32_T Y[72];
|
real32_T Y[72];
|
||||||
for (jy = 0; jy < 6; jy++) {
|
for (i3 = 0; i3 < 6; i3++) {
|
||||||
for (iy = 0; iy < 6; iy++) {
|
for (iy = 0; iy < 6; iy++) {
|
||||||
b_A[iy + 6 * jy] = B[jy + 6 * iy];
|
b_A[iy + 6 * i3] = B[i3 + 6 * iy];
|
||||||
}
|
}
|
||||||
|
|
||||||
ipiv[jy] = (int8_T)(1 + jy);
|
ipiv[i3] = (int8_T)(1 + i3);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 0; j < 5; j++) {
|
for (j = 0; j < 5; j++) {
|
||||||
mmj = -j;
|
c = j * 7;
|
||||||
jj = j * 7;
|
iy = 0;
|
||||||
jp1j = jj + 1;
|
ix = c;
|
||||||
c = mmj + 6;
|
temp = (real32_T)fabs(b_A[c]);
|
||||||
jy = 0;
|
for (k = 2; k <= 6 - j; k++) {
|
||||||
ix = jj;
|
|
||||||
temp = (real32_T)fabsf(b_A[jj]);
|
|
||||||
for (k = 2; k <= c; k++) {
|
|
||||||
ix++;
|
ix++;
|
||||||
s = (real32_T)fabsf(b_A[ix]);
|
s = (real32_T)fabs(b_A[ix]);
|
||||||
if (s > temp) {
|
if (s > temp) {
|
||||||
jy = k - 1;
|
iy = k - 1;
|
||||||
temp = s;
|
temp = s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((real_T)b_A[jj + jy] != 0.0) {
|
if (b_A[c + iy] != 0.0F) {
|
||||||
if (jy != 0) {
|
if (iy != 0) {
|
||||||
ipiv[j] = (int8_T)((j + jy) + 1);
|
ipiv[j] = (int8_T)((j + iy) + 1);
|
||||||
ix = j;
|
ix = j;
|
||||||
iy = j + jy;
|
iy += j;
|
||||||
for (k = 0; k < 6; k++) {
|
for (k = 0; k < 6; k++) {
|
||||||
temp = b_A[ix];
|
temp = b_A[ix];
|
||||||
b_A[ix] = b_A[iy];
|
b_A[ix] = b_A[iy];
|
||||||
@@ -161,42 +156,42 @@ void c_mrdivide(const real32_T A[72], const real32_T B[36], real32_T y[72])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loop_ub = (jp1j + mmj) + 5;
|
i3 = (c - j) + 6;
|
||||||
for (iy = jp1j; iy + 1 <= loop_ub; iy++) {
|
for (jy = c + 1; jy + 1 <= i3; jy++) {
|
||||||
b_A[iy] /= b_A[jj];
|
b_A[jy] /= b_A[c];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c = 5 - j;
|
iy = c;
|
||||||
jy = jj + 6;
|
jy = c + 6;
|
||||||
for (iy = 1; iy <= c; iy++) {
|
for (k = 1; k <= 5 - j; k++) {
|
||||||
if ((real_T)b_A[jy] != 0.0) {
|
temp = b_A[jy];
|
||||||
temp = b_A[jy] * -1.0F;
|
if (b_A[jy] != 0.0F) {
|
||||||
ix = jp1j;
|
ix = c + 1;
|
||||||
loop_ub = (mmj + jj) + 12;
|
i3 = (iy - j) + 12;
|
||||||
for (k = 7 + jj; k + 1 <= loop_ub; k++) {
|
for (ijA = 7 + iy; ijA + 1 <= i3; ijA++) {
|
||||||
b_A[k] += b_A[ix] * temp;
|
b_A[ijA] += b_A[ix] * -temp;
|
||||||
ix++;
|
ix++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jy += 6;
|
jy += 6;
|
||||||
jj += 6;
|
iy += 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (jy = 0; jy < 12; jy++) {
|
for (i3 = 0; i3 < 12; i3++) {
|
||||||
for (iy = 0; iy < 6; iy++) {
|
for (iy = 0; iy < 6; iy++) {
|
||||||
Y[iy + 6 * jy] = A[jy + 12 * iy];
|
Y[iy + 6 * i3] = A[i3 + 12 * iy];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (iy = 0; iy < 6; iy++) {
|
for (jy = 0; jy < 6; jy++) {
|
||||||
if (ipiv[iy] != iy + 1) {
|
if (ipiv[jy] != jy + 1) {
|
||||||
for (j = 0; j < 12; j++) {
|
for (j = 0; j < 12; j++) {
|
||||||
temp = Y[iy + 6 * j];
|
temp = Y[jy + 6 * j];
|
||||||
Y[iy + 6 * j] = Y[(ipiv[iy] + 6 * j) - 1];
|
Y[jy + 6 * j] = Y[(ipiv[jy] + 6 * j) - 1];
|
||||||
Y[(ipiv[iy] + 6 * j) - 1] = temp;
|
Y[(ipiv[jy] + 6 * j) - 1] = temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,10 +199,10 @@ void c_mrdivide(const real32_T A[72], const real32_T B[36], real32_T y[72])
|
|||||||
for (j = 0; j < 12; j++) {
|
for (j = 0; j < 12; j++) {
|
||||||
c = 6 * j;
|
c = 6 * j;
|
||||||
for (k = 0; k < 6; k++) {
|
for (k = 0; k < 6; k++) {
|
||||||
jy = 6 * k;
|
iy = 6 * k;
|
||||||
if ((real_T)Y[k + c] != 0.0) {
|
if (Y[k + c] != 0.0F) {
|
||||||
for (iy = k + 2; iy < 7; iy++) {
|
for (jy = k + 2; jy < 7; jy++) {
|
||||||
Y[(iy + c) - 1] -= Y[k + c] * b_A[(iy + jy) - 1];
|
Y[(jy + c) - 1] -= Y[k + c] * b_A[(jy + iy) - 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,19 +211,19 @@ void c_mrdivide(const real32_T A[72], const real32_T B[36], real32_T y[72])
|
|||||||
for (j = 0; j < 12; j++) {
|
for (j = 0; j < 12; j++) {
|
||||||
c = 6 * j;
|
c = 6 * j;
|
||||||
for (k = 5; k > -1; k += -1) {
|
for (k = 5; k > -1; k += -1) {
|
||||||
jy = 6 * k;
|
iy = 6 * k;
|
||||||
if ((real_T)Y[k + c] != 0.0) {
|
if (Y[k + c] != 0.0F) {
|
||||||
Y[k + c] /= b_A[k + jy];
|
Y[k + c] /= b_A[k + iy];
|
||||||
for (iy = 0; iy + 1 <= k; iy++) {
|
for (jy = 0; jy + 1 <= k; jy++) {
|
||||||
Y[iy + c] -= Y[k + c] * b_A[iy + jy];
|
Y[jy + c] -= Y[k + c] * b_A[jy + iy];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (jy = 0; jy < 6; jy++) {
|
for (i3 = 0; i3 < 6; i3++) {
|
||||||
for (iy = 0; iy < 12; iy++) {
|
for (iy = 0; iy < 12; iy++) {
|
||||||
y[iy + 12 * jy] = Y[jy + 6 * iy];
|
y[iy + 12 * i3] = Y[i3 + 6 * iy];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -238,51 +233,46 @@ void c_mrdivide(const real32_T A[72], const real32_T B[36], real32_T y[72])
|
|||||||
*/
|
*/
|
||||||
void mrdivide(const real32_T A[108], const real32_T B[81], real32_T y[108])
|
void mrdivide(const real32_T A[108], const real32_T B[81], real32_T y[108])
|
||||||
{
|
{
|
||||||
int32_T jy;
|
|
||||||
int32_T iy;
|
|
||||||
real32_T b_A[81];
|
real32_T b_A[81];
|
||||||
int8_T ipiv[9];
|
int8_T ipiv[9];
|
||||||
|
int32_T i2;
|
||||||
|
int32_T iy;
|
||||||
int32_T j;
|
int32_T j;
|
||||||
int32_T mmj;
|
|
||||||
int32_T jj;
|
|
||||||
int32_T jp1j;
|
|
||||||
int32_T c;
|
int32_T c;
|
||||||
int32_T ix;
|
int32_T ix;
|
||||||
real32_T temp;
|
real32_T temp;
|
||||||
int32_T k;
|
int32_T k;
|
||||||
real32_T s;
|
real32_T s;
|
||||||
int32_T loop_ub;
|
int32_T jy;
|
||||||
|
int32_T ijA;
|
||||||
real32_T Y[108];
|
real32_T Y[108];
|
||||||
for (jy = 0; jy < 9; jy++) {
|
for (i2 = 0; i2 < 9; i2++) {
|
||||||
for (iy = 0; iy < 9; iy++) {
|
for (iy = 0; iy < 9; iy++) {
|
||||||
b_A[iy + 9 * jy] = B[jy + 9 * iy];
|
b_A[iy + 9 * i2] = B[i2 + 9 * iy];
|
||||||
}
|
}
|
||||||
|
|
||||||
ipiv[jy] = (int8_T)(1 + jy);
|
ipiv[i2] = (int8_T)(1 + i2);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 0; j < 8; j++) {
|
for (j = 0; j < 8; j++) {
|
||||||
mmj = -j;
|
c = j * 10;
|
||||||
jj = j * 10;
|
iy = 0;
|
||||||
jp1j = jj + 1;
|
ix = c;
|
||||||
c = mmj + 9;
|
temp = (real32_T)fabs(b_A[c]);
|
||||||
jy = 0;
|
for (k = 2; k <= 9 - j; k++) {
|
||||||
ix = jj;
|
|
||||||
temp = (real32_T)fabsf(b_A[jj]);
|
|
||||||
for (k = 2; k <= c; k++) {
|
|
||||||
ix++;
|
ix++;
|
||||||
s = (real32_T)fabsf(b_A[ix]);
|
s = (real32_T)fabs(b_A[ix]);
|
||||||
if (s > temp) {
|
if (s > temp) {
|
||||||
jy = k - 1;
|
iy = k - 1;
|
||||||
temp = s;
|
temp = s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((real_T)b_A[jj + jy] != 0.0) {
|
if (b_A[c + iy] != 0.0F) {
|
||||||
if (jy != 0) {
|
if (iy != 0) {
|
||||||
ipiv[j] = (int8_T)((j + jy) + 1);
|
ipiv[j] = (int8_T)((j + iy) + 1);
|
||||||
ix = j;
|
ix = j;
|
||||||
iy = j + jy;
|
iy += j;
|
||||||
for (k = 0; k < 9; k++) {
|
for (k = 0; k < 9; k++) {
|
||||||
temp = b_A[ix];
|
temp = b_A[ix];
|
||||||
b_A[ix] = b_A[iy];
|
b_A[ix] = b_A[iy];
|
||||||
@@ -292,42 +282,42 @@ void mrdivide(const real32_T A[108], const real32_T B[81], real32_T y[108])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loop_ub = (jp1j + mmj) + 8;
|
i2 = (c - j) + 9;
|
||||||
for (iy = jp1j; iy + 1 <= loop_ub; iy++) {
|
for (jy = c + 1; jy + 1 <= i2; jy++) {
|
||||||
b_A[iy] /= b_A[jj];
|
b_A[jy] /= b_A[c];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c = 8 - j;
|
iy = c;
|
||||||
jy = jj + 9;
|
jy = c + 9;
|
||||||
for (iy = 1; iy <= c; iy++) {
|
for (k = 1; k <= 8 - j; k++) {
|
||||||
if ((real_T)b_A[jy] != 0.0) {
|
temp = b_A[jy];
|
||||||
temp = b_A[jy] * -1.0F;
|
if (b_A[jy] != 0.0F) {
|
||||||
ix = jp1j;
|
ix = c + 1;
|
||||||
loop_ub = (mmj + jj) + 18;
|
i2 = (iy - j) + 18;
|
||||||
for (k = 10 + jj; k + 1 <= loop_ub; k++) {
|
for (ijA = 10 + iy; ijA + 1 <= i2; ijA++) {
|
||||||
b_A[k] += b_A[ix] * temp;
|
b_A[ijA] += b_A[ix] * -temp;
|
||||||
ix++;
|
ix++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jy += 9;
|
jy += 9;
|
||||||
jj += 9;
|
iy += 9;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (jy = 0; jy < 12; jy++) {
|
for (i2 = 0; i2 < 12; i2++) {
|
||||||
for (iy = 0; iy < 9; iy++) {
|
for (iy = 0; iy < 9; iy++) {
|
||||||
Y[iy + 9 * jy] = A[jy + 12 * iy];
|
Y[iy + 9 * i2] = A[i2 + 12 * iy];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (iy = 0; iy < 9; iy++) {
|
for (jy = 0; jy < 9; jy++) {
|
||||||
if (ipiv[iy] != iy + 1) {
|
if (ipiv[jy] != jy + 1) {
|
||||||
for (j = 0; j < 12; j++) {
|
for (j = 0; j < 12; j++) {
|
||||||
temp = Y[iy + 9 * j];
|
temp = Y[jy + 9 * j];
|
||||||
Y[iy + 9 * j] = Y[(ipiv[iy] + 9 * j) - 1];
|
Y[jy + 9 * j] = Y[(ipiv[jy] + 9 * j) - 1];
|
||||||
Y[(ipiv[iy] + 9 * j) - 1] = temp;
|
Y[(ipiv[jy] + 9 * j) - 1] = temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -335,10 +325,10 @@ void mrdivide(const real32_T A[108], const real32_T B[81], real32_T y[108])
|
|||||||
for (j = 0; j < 12; j++) {
|
for (j = 0; j < 12; j++) {
|
||||||
c = 9 * j;
|
c = 9 * j;
|
||||||
for (k = 0; k < 9; k++) {
|
for (k = 0; k < 9; k++) {
|
||||||
jy = 9 * k;
|
iy = 9 * k;
|
||||||
if ((real_T)Y[k + c] != 0.0) {
|
if (Y[k + c] != 0.0F) {
|
||||||
for (iy = k + 2; iy < 10; iy++) {
|
for (jy = k + 2; jy < 10; jy++) {
|
||||||
Y[(iy + c) - 1] -= Y[k + c] * b_A[(iy + jy) - 1];
|
Y[(jy + c) - 1] -= Y[k + c] * b_A[(jy + iy) - 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -347,19 +337,19 @@ void mrdivide(const real32_T A[108], const real32_T B[81], real32_T y[108])
|
|||||||
for (j = 0; j < 12; j++) {
|
for (j = 0; j < 12; j++) {
|
||||||
c = 9 * j;
|
c = 9 * j;
|
||||||
for (k = 8; k > -1; k += -1) {
|
for (k = 8; k > -1; k += -1) {
|
||||||
jy = 9 * k;
|
iy = 9 * k;
|
||||||
if ((real_T)Y[k + c] != 0.0) {
|
if (Y[k + c] != 0.0F) {
|
||||||
Y[k + c] /= b_A[k + jy];
|
Y[k + c] /= b_A[k + iy];
|
||||||
for (iy = 0; iy + 1 <= k; iy++) {
|
for (jy = 0; jy + 1 <= k; jy++) {
|
||||||
Y[iy + c] -= Y[k + c] * b_A[iy + jy];
|
Y[jy + c] -= Y[k + c] * b_A[jy + iy];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (jy = 0; jy < 9; jy++) {
|
for (i2 = 0; i2 < 9; i2++) {
|
||||||
for (iy = 0; iy < 12; iy++) {
|
for (iy = 0; iy < 12; iy++) {
|
||||||
y[iy + 12 * jy] = Y[jy + 9 * iy];
|
y[iy + 12 * i2] = Y[i2 + 9 * iy];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Executable → Regular
+2
-2
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'mrdivide'
|
* Code generation for function 'mrdivide'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
#define __MRDIVIDE_H__
|
#define __MRDIVIDE_H__
|
||||||
/* Include files */
|
/* Include files */
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "rt_defines.h"
|
#include "rt_defines.h"
|
||||||
|
|||||||
Executable → Regular
+11
-19
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'norm'
|
* Code generation for function 'norm'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -31,32 +31,24 @@ real32_T norm(const real32_T x[3])
|
|||||||
{
|
{
|
||||||
real32_T y;
|
real32_T y;
|
||||||
real32_T scale;
|
real32_T scale;
|
||||||
boolean_T firstNonZero;
|
|
||||||
int32_T k;
|
int32_T k;
|
||||||
real32_T absxk;
|
real32_T absxk;
|
||||||
real32_T t;
|
real32_T t;
|
||||||
y = 0.0F;
|
y = 0.0F;
|
||||||
scale = 0.0F;
|
scale = 1.17549435E-38F;
|
||||||
firstNonZero = TRUE;
|
|
||||||
for (k = 0; k < 3; k++) {
|
for (k = 0; k < 3; k++) {
|
||||||
if (x[k] != 0.0F) {
|
absxk = (real32_T)fabs(x[k]);
|
||||||
absxk = (real32_T)fabsf(x[k]);
|
if (absxk > scale) {
|
||||||
if (firstNonZero) {
|
t = scale / absxk;
|
||||||
scale = absxk;
|
y = 1.0F + y * t * t;
|
||||||
y = 1.0F;
|
scale = absxk;
|
||||||
firstNonZero = FALSE;
|
} else {
|
||||||
} else if (scale < absxk) {
|
t = absxk / scale;
|
||||||
t = scale / absxk;
|
y += t * t;
|
||||||
y = 1.0F + y * t * t;
|
|
||||||
scale = absxk;
|
|
||||||
} else {
|
|
||||||
t = absxk / scale;
|
|
||||||
y += t * t;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return scale * (real32_T)sqrtf(y);
|
return scale * (real32_T)sqrt(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End of code generation (norm.c) */
|
/* End of code generation (norm.c) */
|
||||||
|
|||||||
Executable → Regular
+2
-2
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'norm'
|
* Code generation for function 'norm'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
#define __NORM_H__
|
#define __NORM_H__
|
||||||
/* Include files */
|
/* Include files */
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "rt_defines.h"
|
#include "rt_defines.h"
|
||||||
|
|||||||
Executable → Regular
+13
-13
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'power'
|
* Code generation for function 'power'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -27,17 +27,17 @@ static real32_T rt_powf_snf(real32_T u0, real32_T u1);
|
|||||||
static real32_T rt_powf_snf(real32_T u0, real32_T u1)
|
static real32_T rt_powf_snf(real32_T u0, real32_T u1)
|
||||||
{
|
{
|
||||||
real32_T y;
|
real32_T y;
|
||||||
real32_T f0;
|
|
||||||
real32_T f1;
|
real32_T f1;
|
||||||
|
real32_T f2;
|
||||||
if (rtIsNaNF(u0) || rtIsNaNF(u1)) {
|
if (rtIsNaNF(u0) || rtIsNaNF(u1)) {
|
||||||
y = ((real32_T)rtNaN);
|
y = ((real32_T)rtNaN);
|
||||||
} else {
|
} else {
|
||||||
f0 = (real32_T)fabsf(u0);
|
f1 = (real32_T)fabs(u0);
|
||||||
f1 = (real32_T)fabsf(u1);
|
f2 = (real32_T)fabs(u1);
|
||||||
if (rtIsInfF(u1)) {
|
if (rtIsInfF(u1)) {
|
||||||
if (f0 == 1.0F) {
|
if (f1 == 1.0F) {
|
||||||
y = ((real32_T)rtNaN);
|
y = ((real32_T)rtNaN);
|
||||||
} else if (f0 > 1.0F) {
|
} else if (f1 > 1.0F) {
|
||||||
if (u1 > 0.0F) {
|
if (u1 > 0.0F) {
|
||||||
y = ((real32_T)rtInf);
|
y = ((real32_T)rtInf);
|
||||||
} else {
|
} else {
|
||||||
@@ -48,9 +48,9 @@ static real32_T rt_powf_snf(real32_T u0, real32_T u1)
|
|||||||
} else {
|
} else {
|
||||||
y = ((real32_T)rtInf);
|
y = ((real32_T)rtInf);
|
||||||
}
|
}
|
||||||
} else if (f1 == 0.0F) {
|
} else if (f2 == 0.0F) {
|
||||||
y = 1.0F;
|
y = 1.0F;
|
||||||
} else if (f1 == 1.0F) {
|
} else if (f2 == 1.0F) {
|
||||||
if (u1 > 0.0F) {
|
if (u1 > 0.0F) {
|
||||||
y = u0;
|
y = u0;
|
||||||
} else {
|
} else {
|
||||||
@@ -59,11 +59,11 @@ static real32_T rt_powf_snf(real32_T u0, real32_T u1)
|
|||||||
} else if (u1 == 2.0F) {
|
} else if (u1 == 2.0F) {
|
||||||
y = u0 * u0;
|
y = u0 * u0;
|
||||||
} else if ((u1 == 0.5F) && (u0 >= 0.0F)) {
|
} else if ((u1 == 0.5F) && (u0 >= 0.0F)) {
|
||||||
y = (real32_T)sqrtf(u0);
|
y = (real32_T)sqrt(u0);
|
||||||
} else if ((u0 < 0.0F) && (u1 > (real32_T)floorf(u1))) {
|
} else if ((u0 < 0.0F) && (u1 > (real32_T)floor(u1))) {
|
||||||
y = ((real32_T)rtNaN);
|
y = ((real32_T)rtNaN);
|
||||||
} else {
|
} else {
|
||||||
y = (real32_T)powf(u0, u1);
|
y = (real32_T)pow(u0, u1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,11 +73,11 @@ static real32_T rt_powf_snf(real32_T u0, real32_T u1)
|
|||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void power(const real32_T a[12], real_T b, real32_T y[12])
|
void power(const real32_T a[12], real32_T y[12])
|
||||||
{
|
{
|
||||||
int32_T k;
|
int32_T k;
|
||||||
for (k = 0; k < 12; k++) {
|
for (k = 0; k < 12; k++) {
|
||||||
y[k] = rt_powf_snf(a[k], (real32_T)b);
|
y[k] = rt_powf_snf(a[k], 2.0F);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Executable → Regular
+3
-3
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'power'
|
* Code generation for function 'power'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
#define __POWER_H__
|
#define __POWER_H__
|
||||||
/* Include files */
|
/* Include files */
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "rt_defines.h"
|
#include "rt_defines.h"
|
||||||
@@ -29,6 +29,6 @@
|
|||||||
/* Variable Definitions */
|
/* Variable Definitions */
|
||||||
|
|
||||||
/* Function Declarations */
|
/* Function Declarations */
|
||||||
extern void power(const real32_T a[12], real_T b, real32_T y[12]);
|
extern void power(const real32_T a[12], real32_T y[12]);
|
||||||
#endif
|
#endif
|
||||||
/* End of code generation (power.h) */
|
/* End of code generation (power.h) */
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* rdivide.c
|
||||||
|
*
|
||||||
|
* Code generation for function 'rdivide'
|
||||||
|
*
|
||||||
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Include files */
|
||||||
|
#include "rt_nonfinite.h"
|
||||||
|
#include "attitudeKalmanfilter.h"
|
||||||
|
#include "rdivide.h"
|
||||||
|
|
||||||
|
/* Type Definitions */
|
||||||
|
|
||||||
|
/* Named Constants */
|
||||||
|
|
||||||
|
/* Variable Declarations */
|
||||||
|
|
||||||
|
/* Variable Definitions */
|
||||||
|
|
||||||
|
/* Function Declarations */
|
||||||
|
|
||||||
|
/* Function Definitions */
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void rdivide(const real32_T x[3], real32_T y, real32_T z[3])
|
||||||
|
{
|
||||||
|
int32_T i;
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
z[i] = x[i] / y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End of code generation (rdivide.c) */
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* rdivide.h
|
||||||
|
*
|
||||||
|
* Code generation for function 'rdivide'
|
||||||
|
*
|
||||||
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RDIVIDE_H__
|
||||||
|
#define __RDIVIDE_H__
|
||||||
|
/* Include files */
|
||||||
|
#include <math.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "rt_defines.h"
|
||||||
|
#include "rt_nonfinite.h"
|
||||||
|
|
||||||
|
#include "rtwtypes.h"
|
||||||
|
#include "attitudeKalmanfilter_types.h"
|
||||||
|
|
||||||
|
/* Type Definitions */
|
||||||
|
|
||||||
|
/* Named Constants */
|
||||||
|
|
||||||
|
/* Variable Declarations */
|
||||||
|
|
||||||
|
/* Variable Definitions */
|
||||||
|
|
||||||
|
/* Function Declarations */
|
||||||
|
extern void rdivide(const real32_T x[3], real32_T y, real32_T z[3]);
|
||||||
|
#endif
|
||||||
|
/* End of code generation (rdivide.h) */
|
||||||
Executable → Regular
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'attitudeKalmanfilter'
|
* Code generation for function 'attitudeKalmanfilter'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
Executable → Regular
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'attitudeKalmanfilter'
|
* Code generation for function 'attitudeKalmanfilter'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
Executable → Regular
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'attitudeKalmanfilter'
|
* Code generation for function 'attitudeKalmanfilter'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
Executable → Regular
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'attitudeKalmanfilter'
|
* Code generation for function 'attitudeKalmanfilter'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
Executable → Regular
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'attitudeKalmanfilter'
|
* Code generation for function 'attitudeKalmanfilter'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
Executable → Regular
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'attitudeKalmanfilter'
|
* Code generation for function 'attitudeKalmanfilter'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
Executable → Regular
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'attitudeKalmanfilter'
|
* Code generation for function 'attitudeKalmanfilter'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
Executable → Regular
+3
-3
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Code generation for function 'attitudeKalmanfilter'
|
* Code generation for function 'attitudeKalmanfilter'
|
||||||
*
|
*
|
||||||
* C source code generated on: Mon Oct 01 19:38:49 2012
|
* C source code generated on: Tue Oct 16 15:27:58 2012
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -26,8 +26,8 @@
|
|||||||
* Number of bits: char: 8 short: 16 int: 32
|
* Number of bits: char: 8 short: 16 int: 32
|
||||||
* long: 32 native word size: 32
|
* long: 32 native word size: 32
|
||||||
* Byte ordering: LittleEndian
|
* Byte ordering: LittleEndian
|
||||||
* Signed integer division rounds to: Zero
|
* Signed integer division rounds to: Undefined
|
||||||
* Shift right on a signed integer as arithmetic shift: on
|
* Shift right on a signed integer as arithmetic shift: off
|
||||||
*=======================================================================*/
|
*=======================================================================*/
|
||||||
|
|
||||||
/*=======================================================================*
|
/*=======================================================================*
|
||||||
|
|||||||
@@ -0,0 +1,175 @@
|
|||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "calibration_routines.h"
|
||||||
|
|
||||||
|
|
||||||
|
int sphere_fit_least_squares(const float x[], const float y[], const float z[],
|
||||||
|
unsigned int size, unsigned int max_iterations, float delta, float *sphere_x, float *sphere_y, float *sphere_z, float *sphere_radius) {
|
||||||
|
|
||||||
|
float x_sumplain = 0.0f;
|
||||||
|
float x_sumsq = 0.0f;
|
||||||
|
float x_sumcube = 0.0f;
|
||||||
|
|
||||||
|
float y_sumplain = 0.0f;
|
||||||
|
float y_sumsq = 0.0f;
|
||||||
|
float y_sumcube = 0.0f;
|
||||||
|
|
||||||
|
float z_sumplain = 0.0f;
|
||||||
|
float z_sumsq = 0.0f;
|
||||||
|
float z_sumcube = 0.0f;
|
||||||
|
|
||||||
|
float xy_sum = 0.0f;
|
||||||
|
float xz_sum = 0.0f;
|
||||||
|
float yz_sum = 0.0f;
|
||||||
|
|
||||||
|
float x2y_sum = 0.0f;
|
||||||
|
float x2z_sum = 0.0f;
|
||||||
|
float y2x_sum = 0.0f;
|
||||||
|
float y2z_sum = 0.0f;
|
||||||
|
float z2x_sum = 0.0f;
|
||||||
|
float z2y_sum = 0.0f;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < size; i++) {
|
||||||
|
|
||||||
|
float x2 = x[i] * x[i];
|
||||||
|
float y2 = y[i] * y[i];
|
||||||
|
float z2 = z[i] * z[i];
|
||||||
|
|
||||||
|
x_sumplain += x[i];
|
||||||
|
x_sumsq += x2;
|
||||||
|
x_sumcube += x2 * x[i];
|
||||||
|
|
||||||
|
y_sumplain += y[i];
|
||||||
|
y_sumsq += y2;
|
||||||
|
y_sumcube += y2 * y[i];
|
||||||
|
|
||||||
|
z_sumplain += z[i];
|
||||||
|
z_sumsq += z2;
|
||||||
|
z_sumcube += z2 * z[i];
|
||||||
|
|
||||||
|
xy_sum += x[i] * y[i];
|
||||||
|
xz_sum += x[i] * z[i];
|
||||||
|
yz_sum += y[i] * z[i];
|
||||||
|
|
||||||
|
x2y_sum += x2 * y[i];
|
||||||
|
x2z_sum += x2 * z[i];
|
||||||
|
|
||||||
|
y2x_sum += y2 * x[i];
|
||||||
|
y2z_sum += y2 * z[i];
|
||||||
|
|
||||||
|
z2x_sum += z2 * x[i];
|
||||||
|
z2y_sum += z2 * y[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//Least Squares Fit a sphere A,B,C with radius squared Rsq to 3D data
|
||||||
|
//
|
||||||
|
// P is a structure that has been computed with the data earlier.
|
||||||
|
// P.npoints is the number of elements; the length of X,Y,Z are identical.
|
||||||
|
// P's members are logically named.
|
||||||
|
//
|
||||||
|
// X[n] is the x component of point n
|
||||||
|
// Y[n] is the y component of point n
|
||||||
|
// Z[n] is the z component of point n
|
||||||
|
//
|
||||||
|
// A is the x coordiante of the sphere
|
||||||
|
// B is the y coordiante of the sphere
|
||||||
|
// C is the z coordiante of the sphere
|
||||||
|
// Rsq is the radius squared of the sphere.
|
||||||
|
//
|
||||||
|
//This method should converge; maybe 5-100 iterations or more.
|
||||||
|
//
|
||||||
|
float x_sum = x_sumplain / size; //sum( X[n] )
|
||||||
|
float x_sum2 = x_sumsq / size; //sum( X[n]^2 )
|
||||||
|
float x_sum3 = x_sumcube / size; //sum( X[n]^3 )
|
||||||
|
float y_sum = y_sumplain / size; //sum( Y[n] )
|
||||||
|
float y_sum2 = y_sumsq / size; //sum( Y[n]^2 )
|
||||||
|
float y_sum3 = y_sumcube / size; //sum( Y[n]^3 )
|
||||||
|
float z_sum = z_sumplain / size; //sum( Z[n] )
|
||||||
|
float z_sum2 = z_sumsq / size; //sum( Z[n]^2 )
|
||||||
|
float z_sum3 = z_sumcube / size; //sum( Z[n]^3 )
|
||||||
|
|
||||||
|
float XY = xy_sum / size; //sum( X[n] * Y[n] )
|
||||||
|
float XZ = xz_sum / size; //sum( X[n] * Z[n] )
|
||||||
|
float YZ = yz_sum / size; //sum( Y[n] * Z[n] )
|
||||||
|
float X2Y = x2y_sum / size; //sum( X[n]^2 * Y[n] )
|
||||||
|
float X2Z = x2z_sum / size; //sum( X[n]^2 * Z[n] )
|
||||||
|
float Y2X = y2x_sum / size; //sum( Y[n]^2 * X[n] )
|
||||||
|
float Y2Z = y2z_sum / size; //sum( Y[n]^2 * Z[n] )
|
||||||
|
float Z2X = z2x_sum / size; //sum( Z[n]^2 * X[n] )
|
||||||
|
float Z2Y = z2y_sum / size; //sum( Z[n]^2 * Y[n] )
|
||||||
|
|
||||||
|
//Reduction of multiplications
|
||||||
|
float F0 = x_sum2 + y_sum2 + z_sum2;
|
||||||
|
float F1 = 0.5f * F0;
|
||||||
|
float F2 = -8.0f * (x_sum3 + Y2X + Z2X);
|
||||||
|
float F3 = -8.0f * (X2Y + y_sum3 + Z2Y);
|
||||||
|
float F4 = -8.0f * (X2Z + Y2Z + z_sum3);
|
||||||
|
|
||||||
|
//Set initial conditions:
|
||||||
|
float A = x_sum;
|
||||||
|
float B = y_sum;
|
||||||
|
float C = z_sum;
|
||||||
|
|
||||||
|
//First iteration computation:
|
||||||
|
float A2 = A*A;
|
||||||
|
float B2 = B*B;
|
||||||
|
float C2 = C*C;
|
||||||
|
float QS = A2 + B2 + C2;
|
||||||
|
float QB = -2.0f * (A*x_sum + B*y_sum + C*z_sum);
|
||||||
|
|
||||||
|
//Set initial conditions:
|
||||||
|
float Rsq = F0 + QB + QS;
|
||||||
|
|
||||||
|
//First iteration computation:
|
||||||
|
float Q0 = 0.5f * (QS - Rsq);
|
||||||
|
float Q1 = F1 + Q0;
|
||||||
|
float Q2 = 8.0f * ( QS - Rsq + QB + F0 );
|
||||||
|
float aA,aB,aC,nA,nB,nC,dA,dB,dC;
|
||||||
|
|
||||||
|
//Iterate N times, ignore stop condition.
|
||||||
|
int n = 0;
|
||||||
|
while( n < max_iterations ){
|
||||||
|
n++;
|
||||||
|
|
||||||
|
//Compute denominator:
|
||||||
|
aA = Q2 + 16.0f * (A2 - 2.0f * A*x_sum + x_sum2);
|
||||||
|
aB = Q2 + 16.0f *(B2 - 2.0f * B*y_sum + y_sum2);
|
||||||
|
aC = Q2 + 16.0f *(C2 - 2.0f * C*z_sum + z_sum2);
|
||||||
|
aA = (aA == 0.0f) ? 1.0f : aA;
|
||||||
|
aB = (aB == 0.0f) ? 1.0f : aB;
|
||||||
|
aC = (aC == 0.0f) ? 1.0f : aC;
|
||||||
|
|
||||||
|
//Compute next iteration
|
||||||
|
nA = A - ((F2 + 16.0f * ( B*XY + C*XZ + x_sum*(-A2 - Q0) + A*(x_sum2 + Q1 - C*z_sum - B*y_sum) ) )/aA);
|
||||||
|
nB = B - ((F3 + 16.0f * ( A*XY + C*YZ + y_sum*(-B2 - Q0) + B*(y_sum2 + Q1 - A*x_sum - C*z_sum) ) )/aB);
|
||||||
|
nC = C - ((F4 + 16.0f * ( A*XZ + B*YZ + z_sum*(-C2 - Q0) + C*(z_sum2 + Q1 - A*x_sum - B*y_sum) ) )/aC);
|
||||||
|
|
||||||
|
//Check for stop condition
|
||||||
|
dA = (nA - A);
|
||||||
|
dB = (nB - B);
|
||||||
|
dC = (nC - C);
|
||||||
|
if( (dA*dA + dB*dB + dC*dC) <= delta ){ break; }
|
||||||
|
|
||||||
|
//Compute next iteration's values
|
||||||
|
A = nA;
|
||||||
|
B = nB;
|
||||||
|
C = nC;
|
||||||
|
A2 = A*A;
|
||||||
|
B2 = B*B;
|
||||||
|
C2 = C*C;
|
||||||
|
QS = A2 + B2 + C2;
|
||||||
|
QB = -2.0f * (A*x_sum + B*y_sum + C*z_sum);
|
||||||
|
Rsq = F0 + QB + QS;
|
||||||
|
Q0 = 0.5f * (QS - Rsq);
|
||||||
|
Q1 = F1 + Q0;
|
||||||
|
Q2 = 8.0f * ( QS - Rsq + QB + F0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
*sphere_x = A;
|
||||||
|
*sphere_y = B;
|
||||||
|
*sphere_z = C;
|
||||||
|
*sphere_radius = sqrtf(Rsq);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* Least-squares fit of a sphere to a set of points.
|
||||||
|
*
|
||||||
|
* Fits a sphere to a set of points on the sphere surface.
|
||||||
|
*
|
||||||
|
* @param x point coordinates on the X axis
|
||||||
|
* @param y point coordinates on the Y axis
|
||||||
|
* @param z point coordinates on the Z axis
|
||||||
|
* @param size number of points
|
||||||
|
* @param max_iterations abort if maximum number of iterations have been reached. If unsure, set to 100.
|
||||||
|
* @param delta abort if error is below delta. If unsure, set to 0 to run max_iterations times.
|
||||||
|
* @param sphere_x coordinate of the sphere center on the X axis
|
||||||
|
* @param sphere_y coordinate of the sphere center on the Y axis
|
||||||
|
* @param sphere_z coordinate of the sphere center on the Z axis
|
||||||
|
* @param sphere_radius sphere radius
|
||||||
|
*
|
||||||
|
* @return 0 on success, 1 on failure
|
||||||
|
*/
|
||||||
|
int sphere_fit_least_squares(const float x[], const float y[], const float z[],
|
||||||
|
unsigned int size, unsigned int max_iterations, float delta, float *sphere_x, float *sphere_y, float *sphere_z, float *sphere_radius);
|
||||||
+317
-218
File diff suppressed because it is too large
Load Diff
@@ -504,7 +504,7 @@ void update_state_machine_mode_manual(int status_pub, struct vehicle_status_s *c
|
|||||||
current_status->flag_control_manual_enabled = true;
|
current_status->flag_control_manual_enabled = true;
|
||||||
/* enable attitude control per default */
|
/* enable attitude control per default */
|
||||||
current_status->flag_control_attitude_enabled = true;
|
current_status->flag_control_attitude_enabled = true;
|
||||||
current_status->flag_control_rates_enabled = false; // XXX
|
current_status->flag_control_rates_enabled = true;
|
||||||
if (old_mode != current_status->flight_mode) state_machine_publish(status_pub, current_status, mavlink_fd);
|
if (old_mode != current_status->flight_mode) state_machine_publish(status_pub, current_status, mavlink_fd);
|
||||||
|
|
||||||
if (current_status->state_machine == SYSTEM_STATE_GROUND_READY || current_status->state_machine == SYSTEM_STATE_STABILIZED || current_status->state_machine == SYSTEM_STATE_AUTO) {
|
if (current_status->state_machine == SYSTEM_STATE_GROUND_READY || current_status->state_machine == SYSTEM_STATE_STABILIZED || current_status->state_machine == SYSTEM_STATE_AUTO) {
|
||||||
@@ -519,7 +519,7 @@ void update_state_machine_mode_stabilized(int status_pub, struct vehicle_status_
|
|||||||
current_status->flight_mode = VEHICLE_FLIGHT_MODE_STABILIZED;
|
current_status->flight_mode = VEHICLE_FLIGHT_MODE_STABILIZED;
|
||||||
current_status->flag_control_manual_enabled = true;
|
current_status->flag_control_manual_enabled = true;
|
||||||
current_status->flag_control_attitude_enabled = true;
|
current_status->flag_control_attitude_enabled = true;
|
||||||
current_status->flag_control_rates_enabled = false; // XXX
|
current_status->flag_control_rates_enabled = true;
|
||||||
if (old_mode != current_status->flight_mode) state_machine_publish(status_pub, current_status, mavlink_fd);
|
if (old_mode != current_status->flight_mode) state_machine_publish(status_pub, current_status, mavlink_fd);
|
||||||
|
|
||||||
if (current_status->state_machine == SYSTEM_STATE_GROUND_READY || current_status->state_machine == SYSTEM_STATE_MANUAL || current_status->state_machine == SYSTEM_STATE_AUTO) {
|
if (current_status->state_machine == SYSTEM_STATE_GROUND_READY || current_status->state_machine == SYSTEM_STATE_MANUAL || current_status->state_machine == SYSTEM_STATE_AUTO) {
|
||||||
@@ -534,7 +534,7 @@ void update_state_machine_mode_auto(int status_pub, struct vehicle_status_s *cur
|
|||||||
current_status->flight_mode = VEHICLE_FLIGHT_MODE_AUTO;
|
current_status->flight_mode = VEHICLE_FLIGHT_MODE_AUTO;
|
||||||
current_status->flag_control_manual_enabled = true;
|
current_status->flag_control_manual_enabled = true;
|
||||||
current_status->flag_control_attitude_enabled = true;
|
current_status->flag_control_attitude_enabled = true;
|
||||||
current_status->flag_control_rates_enabled = false; // XXX
|
current_status->flag_control_rates_enabled = true;
|
||||||
if (old_mode != current_status->flight_mode) state_machine_publish(status_pub, current_status, mavlink_fd);
|
if (old_mode != current_status->flight_mode) state_machine_publish(status_pub, current_status, mavlink_fd);
|
||||||
|
|
||||||
if (current_status->state_machine == SYSTEM_STATE_GROUND_READY || current_status->state_machine == SYSTEM_STATE_MANUAL || current_status->state_machine == SYSTEM_STATE_STABILIZED) {
|
if (current_status->state_machine == SYSTEM_STATE_GROUND_READY || current_status->state_machine == SYSTEM_STATE_MANUAL || current_status->state_machine == SYSTEM_STATE_STABILIZED) {
|
||||||
|
|||||||
@@ -99,7 +99,13 @@ ORB_DECLARE(sensor_mag);
|
|||||||
/** copy the mag scaling constants to the structure pointed to by (arg) */
|
/** copy the mag scaling constants to the structure pointed to by (arg) */
|
||||||
#define MAGIOCGSCALE _MAGIOC(3)
|
#define MAGIOCGSCALE _MAGIOC(3)
|
||||||
|
|
||||||
|
/** set the measurement range to handle (at least) arg Gauss */
|
||||||
|
#define MAGIOCSRANGE _MAGIOC(4)
|
||||||
|
|
||||||
/** perform self-calibration, update scale factors to canonical units */
|
/** perform self-calibration, update scale factors to canonical units */
|
||||||
#define MAGIOCCALIBRATE _MAGIOC(4)
|
#define MAGIOCCALIBRATE _MAGIOC(5)
|
||||||
|
|
||||||
|
/** excite strap */
|
||||||
|
#define MAGIOCEXSTRAP _MAGIOC(6)
|
||||||
|
|
||||||
#endif /* _DRV_MAG_H */
|
#endif /* _DRV_MAG_H */
|
||||||
|
|||||||
@@ -63,8 +63,6 @@
|
|||||||
#define _TONE_ALARM_BASE 0x7400
|
#define _TONE_ALARM_BASE 0x7400
|
||||||
#define TONE_SET_ALARM _IOC(_TONE_ALARM_BASE, 1)
|
#define TONE_SET_ALARM _IOC(_TONE_ALARM_BASE, 1)
|
||||||
|
|
||||||
extern int tone_alarm_init(void);
|
|
||||||
|
|
||||||
/* structure describing one note in a tone pattern */
|
/* structure describing one note in a tone pattern */
|
||||||
struct tone_note {
|
struct tone_note {
|
||||||
uint8_t pitch;
|
uint8_t pitch;
|
||||||
@@ -127,4 +125,4 @@ enum tone_pitch {
|
|||||||
TONE_NOTE_MAX
|
TONE_NOTE_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* DRV_TONE_ALARM_H_ */
|
#endif /* DRV_TONE_ALARM_H_ */
|
||||||
@@ -37,6 +37,6 @@
|
|||||||
|
|
||||||
APPNAME = hmc5883
|
APPNAME = hmc5883
|
||||||
PRIORITY = SCHED_PRIORITY_DEFAULT
|
PRIORITY = SCHED_PRIORITY_DEFAULT
|
||||||
STACKSIZE = 2048
|
STACKSIZE = 4096
|
||||||
|
|
||||||
include $(APPDIR)/mk/app.mk
|
include $(APPDIR)/mk/app.mk
|
||||||
|
|||||||
@@ -175,6 +175,36 @@ private:
|
|||||||
*/
|
*/
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform the on-sensor scale calibration routine.
|
||||||
|
*
|
||||||
|
* @note The sensor will continue to provide measurements, these
|
||||||
|
* will however reflect the uncalibrated sensor state until
|
||||||
|
* the calibration routine has been completed.
|
||||||
|
*
|
||||||
|
* @param enable set to 1 to enable self-test strap, 0 to disable
|
||||||
|
*/
|
||||||
|
int calibrate(struct file *filp, unsigned enable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform the on-sensor scale calibration routine.
|
||||||
|
*
|
||||||
|
* @note The sensor will continue to provide measurements, these
|
||||||
|
* will however reflect the uncalibrated sensor state until
|
||||||
|
* the calibration routine has been completed.
|
||||||
|
*
|
||||||
|
* @param enable set to 1 to enable self-test positive strap, -1 to enable
|
||||||
|
* negative strap, 0 to set to normal mode
|
||||||
|
*/
|
||||||
|
int set_excitement(unsigned enable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the sensor range.
|
||||||
|
*
|
||||||
|
* Sets the internal range to handle at least the argument in Gauss.
|
||||||
|
*/
|
||||||
|
int set_range(unsigned range);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform a poll cycle; collect from the previous measurement
|
* Perform a poll cycle; collect from the previous measurement
|
||||||
* and start a new one.
|
* and start a new one.
|
||||||
@@ -254,9 +284,9 @@ HMC5883::HMC5883(int bus) :
|
|||||||
_next_report(0),
|
_next_report(0),
|
||||||
_oldest_report(0),
|
_oldest_report(0),
|
||||||
_reports(nullptr),
|
_reports(nullptr),
|
||||||
|
_range_scale(0), /* default range scale from counts to gauss */
|
||||||
|
_range_ga(1.3f),
|
||||||
_mag_topic(-1),
|
_mag_topic(-1),
|
||||||
_range_scale(1.0f / 1090.0f), /* default range scale from counts to gauss */
|
|
||||||
_range_ga(0.88f),
|
|
||||||
_sample_perf(perf_alloc(PC_ELAPSED, "hmc5883_read")),
|
_sample_perf(perf_alloc(PC_ELAPSED, "hmc5883_read")),
|
||||||
_comms_errors(perf_alloc(PC_COUNT, "hmc5883_comms_errors")),
|
_comms_errors(perf_alloc(PC_COUNT, "hmc5883_comms_errors")),
|
||||||
_buffer_overflows(perf_alloc(PC_COUNT, "hmc5883_buffer_overflows"))
|
_buffer_overflows(perf_alloc(PC_COUNT, "hmc5883_buffer_overflows"))
|
||||||
@@ -308,11 +338,71 @@ HMC5883::init()
|
|||||||
if (_mag_topic < 0)
|
if (_mag_topic < 0)
|
||||||
debug("failed to create sensor_mag object");
|
debug("failed to create sensor_mag object");
|
||||||
|
|
||||||
|
/* set range */
|
||||||
|
set_range(_range_ga);
|
||||||
|
|
||||||
ret = OK;
|
ret = OK;
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int HMC5883::set_range(unsigned range)
|
||||||
|
{
|
||||||
|
uint8_t range_bits;
|
||||||
|
|
||||||
|
if (range < 1) {
|
||||||
|
range_bits = 0x00;
|
||||||
|
_range_scale = 1.0f / 1370.0f;
|
||||||
|
_range_ga = 0.88f;
|
||||||
|
} else if (range <= 1) {
|
||||||
|
range_bits = 0x01;
|
||||||
|
_range_scale = 1.0f / 1090.0f;
|
||||||
|
_range_ga = 1.3f;
|
||||||
|
} else if (range <= 2) {
|
||||||
|
range_bits = 0x02;
|
||||||
|
_range_scale = 1.0f / 820.0f;
|
||||||
|
_range_ga = 1.9f;
|
||||||
|
} else if (range <= 3) {
|
||||||
|
range_bits = 0x03;
|
||||||
|
_range_scale = 1.0f / 660.0f;
|
||||||
|
_range_ga = 2.5f;
|
||||||
|
} else if (range <= 4) {
|
||||||
|
range_bits = 0x04;
|
||||||
|
_range_scale = 1.0f / 440.0f;
|
||||||
|
_range_ga = 4.0f;
|
||||||
|
} else if (range <= 4.7f) {
|
||||||
|
range_bits = 0x05;
|
||||||
|
_range_scale = 1.0f / 390.0f;
|
||||||
|
_range_ga = 4.7f;
|
||||||
|
} else if (range <= 5.6f) {
|
||||||
|
range_bits = 0x06;
|
||||||
|
_range_scale = 1.0f / 330.0f;
|
||||||
|
_range_ga = 5.6f;
|
||||||
|
} else {
|
||||||
|
range_bits = 0x07;
|
||||||
|
_range_scale = 1.0f / 230.0f;
|
||||||
|
_range_ga = 8.1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send the command to set the range
|
||||||
|
*/
|
||||||
|
ret = write_reg(ADDR_CONF_B, (range_bits << 5));
|
||||||
|
|
||||||
|
if (OK != ret)
|
||||||
|
perf_count(_comms_errors);
|
||||||
|
|
||||||
|
uint8_t range_bits_in;
|
||||||
|
ret = read_reg(ADDR_CONF_B, range_bits_in);
|
||||||
|
|
||||||
|
if (OK != ret)
|
||||||
|
perf_count(_comms_errors);
|
||||||
|
|
||||||
|
return !(range_bits_in == (range_bits << 5));
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
HMC5883::probe()
|
HMC5883::probe()
|
||||||
{
|
{
|
||||||
@@ -495,6 +585,9 @@ HMC5883::ioctl(struct file *filp, int cmd, unsigned long arg)
|
|||||||
/* not supported, always 1 sample per poll */
|
/* not supported, always 1 sample per poll */
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
case MAGIOCSRANGE:
|
||||||
|
return set_range(arg);
|
||||||
|
|
||||||
case MAGIOCSLOWPASS:
|
case MAGIOCSLOWPASS:
|
||||||
/* not supported, no internal filtering */
|
/* not supported, no internal filtering */
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -510,8 +603,10 @@ HMC5883::ioctl(struct file *filp, int cmd, unsigned long arg)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case MAGIOCCALIBRATE:
|
case MAGIOCCALIBRATE:
|
||||||
/* XXX perform auto-calibration */
|
return calibrate(filp, arg);
|
||||||
return -EINVAL;
|
|
||||||
|
case MAGIOCEXSTRAP:
|
||||||
|
return set_excitement(arg);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* give it to the superclass */
|
/* give it to the superclass */
|
||||||
@@ -718,6 +813,194 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int HMC5883::calibrate(struct file *filp, unsigned enable)
|
||||||
|
{
|
||||||
|
struct mag_report report;
|
||||||
|
ssize_t sz;
|
||||||
|
int ret = 1;
|
||||||
|
|
||||||
|
// XXX do something smarter here
|
||||||
|
int fd = (int)enable;
|
||||||
|
|
||||||
|
struct mag_scale mscale_previous = {
|
||||||
|
0.0f,
|
||||||
|
1.0f,
|
||||||
|
0.0f,
|
||||||
|
1.0f,
|
||||||
|
0.0f,
|
||||||
|
1.0f,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mag_scale mscale_null = {
|
||||||
|
0.0f,
|
||||||
|
1.0f,
|
||||||
|
0.0f,
|
||||||
|
1.0f,
|
||||||
|
0.0f,
|
||||||
|
1.0f,
|
||||||
|
};
|
||||||
|
|
||||||
|
float avg_excited[3] = {0.0f, 0.0f, 0.0f};
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
warnx("starting mag scale calibration");
|
||||||
|
|
||||||
|
/* do a simple demand read */
|
||||||
|
sz = read(filp, (char*)&report, sizeof(report));
|
||||||
|
if (sz != sizeof(report)) {
|
||||||
|
warn("immediate read failed");
|
||||||
|
ret = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
warnx("current measurement: %.6f %.6f %.6f", (double)report.x, (double)report.y, (double)report.z);
|
||||||
|
warnx("time: %lld", report.timestamp);
|
||||||
|
warnx("sampling 500 samples for scaling offset");
|
||||||
|
|
||||||
|
/* set the queue depth to 10 */
|
||||||
|
if (OK != ioctl(filp, SENSORIOCSQUEUEDEPTH, 10)) {
|
||||||
|
warn("failed to set queue depth");
|
||||||
|
ret = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* start the sensor polling at 50 Hz */
|
||||||
|
if (OK != ioctl(filp, SENSORIOCSPOLLRATE, 50)) {
|
||||||
|
warn("failed to set 2Hz poll rate");
|
||||||
|
ret = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set to 2.5 Gauss */
|
||||||
|
if (OK != ioctl(filp, MAGIOCSRANGE, 2)) {
|
||||||
|
warnx("failed to set 2.5 Ga range");
|
||||||
|
ret = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OK != ioctl(filp, MAGIOCEXSTRAP, 1)) {
|
||||||
|
warnx("failed to enable sensor calibration mode");
|
||||||
|
ret = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OK != ioctl(filp, MAGIOCGSCALE, (long unsigned int)&mscale_previous)) {
|
||||||
|
warn("WARNING: failed to get scale / offsets for mag");
|
||||||
|
ret = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OK != ioctl(filp, MAGIOCSSCALE, (long unsigned int)&mscale_null)) {
|
||||||
|
warn("WARNING: failed to set null scale / offsets for mag");
|
||||||
|
ret = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read the sensor 10x and report each value */
|
||||||
|
for (i = 0; i < 500; i++) {
|
||||||
|
struct pollfd fds;
|
||||||
|
|
||||||
|
/* wait for data to be ready */
|
||||||
|
fds.fd = fd;
|
||||||
|
fds.events = POLLIN;
|
||||||
|
ret = ::poll(&fds, 1, 2000);
|
||||||
|
|
||||||
|
if (ret != 1) {
|
||||||
|
warn("timed out waiting for sensor data");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now go get it */
|
||||||
|
sz = ::read(fd, &report, sizeof(report));
|
||||||
|
|
||||||
|
if (sz != sizeof(report)) {
|
||||||
|
warn("periodic read failed");
|
||||||
|
goto out;
|
||||||
|
} else {
|
||||||
|
avg_excited[0] += report.x;
|
||||||
|
avg_excited[1] += report.y;
|
||||||
|
avg_excited[2] += report.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
//warnx("periodic read %u", i);
|
||||||
|
//warnx("measurement: %.6f %.6f %.6f", (double)report.x, (double)report.y, (double)report.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
avg_excited[0] /= i;
|
||||||
|
avg_excited[1] /= i;
|
||||||
|
avg_excited[2] /= i;
|
||||||
|
|
||||||
|
warnx("done. Performed %u reads", i);
|
||||||
|
warnx("measurement avg: %.6f %.6f %.6f", (double)avg_excited[0], (double)avg_excited[1], (double)avg_excited[2]);
|
||||||
|
|
||||||
|
float scaling[3];
|
||||||
|
|
||||||
|
/* calculate axis scaling */
|
||||||
|
scaling[0] = fabsf(1.16f / avg_excited[0]);
|
||||||
|
/* second axis inverted */
|
||||||
|
scaling[1] = fabsf(1.16f / -avg_excited[1]);
|
||||||
|
scaling[2] = fabsf(1.08f / avg_excited[2]);
|
||||||
|
|
||||||
|
warnx("axes scaling: %.6f %.6f %.6f", (double)scaling[0], (double)scaling[1], (double)scaling[2]);
|
||||||
|
|
||||||
|
/* set back to normal mode */
|
||||||
|
/* Set to 1.1 Gauss */
|
||||||
|
if (OK != ::ioctl(fd, MAGIOCSRANGE, 1)) {
|
||||||
|
warnx("failed to set 1.1 Ga range");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OK != ::ioctl(fd, MAGIOCEXSTRAP, 0)) {
|
||||||
|
warnx("failed to disable sensor calibration mode");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set scaling in device */
|
||||||
|
mscale_previous.x_scale = scaling[0];
|
||||||
|
mscale_previous.y_scale = scaling[1];
|
||||||
|
mscale_previous.z_scale = scaling[2];
|
||||||
|
|
||||||
|
if (OK != ioctl(filp, MAGIOCSSCALE, (long unsigned int)&mscale_previous)) {
|
||||||
|
warn("WARNING: failed to set new scale / offsets for mag");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = OK;
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (ret == OK) {
|
||||||
|
warnx("mag scale calibration successfully finished.");
|
||||||
|
} else {
|
||||||
|
warnx("mag scale calibration failed.");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int HMC5883::set_excitement(unsigned enable)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
/* arm the excitement strap */
|
||||||
|
uint8_t conf_reg;
|
||||||
|
ret = read_reg(ADDR_CONF_A, conf_reg);
|
||||||
|
if (OK != ret)
|
||||||
|
perf_count(_comms_errors);
|
||||||
|
if (((int)enable) < 0) {
|
||||||
|
conf_reg |= 0x01;
|
||||||
|
} else if (enable > 0) {
|
||||||
|
conf_reg |= 0x02;
|
||||||
|
} else {
|
||||||
|
conf_reg &= ~0x03;
|
||||||
|
}
|
||||||
|
ret = write_reg(ADDR_CONF_A, conf_reg);
|
||||||
|
if (OK != ret)
|
||||||
|
perf_count(_comms_errors);
|
||||||
|
|
||||||
|
uint8_t conf_reg_ret;
|
||||||
|
read_reg(ADDR_CONF_A, conf_reg_ret);
|
||||||
|
|
||||||
|
return !(conf_reg == conf_reg_ret);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
HMC5883::write_reg(uint8_t reg, uint8_t val)
|
HMC5883::write_reg(uint8_t reg, uint8_t val)
|
||||||
{
|
{
|
||||||
@@ -775,6 +1058,7 @@ void start();
|
|||||||
void test();
|
void test();
|
||||||
void reset();
|
void reset();
|
||||||
void info();
|
void info();
|
||||||
|
int calibrate();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the driver.
|
* Start the driver.
|
||||||
@@ -872,6 +1156,69 @@ test()
|
|||||||
errx(0, "PASS");
|
errx(0, "PASS");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Automatic scale calibration.
|
||||||
|
*
|
||||||
|
* Basic idea:
|
||||||
|
*
|
||||||
|
* output = (ext field +- 1.1 Ga self-test) * scale factor
|
||||||
|
*
|
||||||
|
* and consequently:
|
||||||
|
*
|
||||||
|
* 1.1 Ga = (excited - normal) * scale factor
|
||||||
|
* scale factor = (excited - normal) / 1.1 Ga
|
||||||
|
*
|
||||||
|
* sxy = (excited - normal) / 766 | for conf reg. B set to 0x60 / Gain = 3
|
||||||
|
* sz = (excited - normal) / 713 | for conf reg. B set to 0x60 / Gain = 3
|
||||||
|
*
|
||||||
|
* By subtracting the non-excited measurement the pure 1.1 Ga reading
|
||||||
|
* can be extracted and the sensitivity of all axes can be matched.
|
||||||
|
*
|
||||||
|
* SELF TEST OPERATION
|
||||||
|
* To check the HMC5883L for proper operation, a self test feature in incorporated
|
||||||
|
* in which the sensor offset straps are excited to create a nominal field strength
|
||||||
|
* (bias field) to be measured. To implement self test, the least significant bits
|
||||||
|
* (MS1 and MS0) of configuration register A are changed from 00 to 01 (positive bias)
|
||||||
|
* or 10 (negetive bias), e.g. 0x11 or 0x12.
|
||||||
|
* Then, by placing the mode register into single-measurement mode (0x01),
|
||||||
|
* two data acquisition cycles will be made on each magnetic vector.
|
||||||
|
* The first acquisition will be a set pulse followed shortly by measurement
|
||||||
|
* data of the external field. The second acquisition will have the offset strap
|
||||||
|
* excited (about 10 mA) in the positive bias mode for X, Y, and Z axes to create
|
||||||
|
* about a ±1.1 gauss self test field plus the external field. The first acquisition
|
||||||
|
* values will be subtracted from the second acquisition, and the net measurement
|
||||||
|
* will be placed into the data output registers.
|
||||||
|
* Since self test adds ~1.1 Gauss additional field to the existing field strength,
|
||||||
|
* using a reduced gain setting prevents sensor from being saturated and data registers
|
||||||
|
* overflowed. For example, if the configuration register B is set to 0x60 (Gain=3),
|
||||||
|
* values around +766 LSB (1.16 Ga * 660 LSB/Ga) will be placed in the X and Y data
|
||||||
|
* output registers and around +713 (1.08 Ga * 660 LSB/Ga) will be placed in Z data
|
||||||
|
* output register. To leave the self test mode, change MS1 and MS0 bit of the
|
||||||
|
* configuration register A back to 00 (Normal Measurement Mode), e.g. 0x10.
|
||||||
|
* Using the self test method described above, the user can scale sensor
|
||||||
|
*/
|
||||||
|
int calibrate()
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
int fd = open(MAG_DEVICE_PATH, O_RDONLY);
|
||||||
|
if (fd < 0)
|
||||||
|
err(1, "%s open failed (try 'hmc5883 start' if the driver is not running", MAG_DEVICE_PATH);
|
||||||
|
|
||||||
|
if (OK != (ret = ioctl(fd, MAGIOCCALIBRATE, fd))) {
|
||||||
|
warnx("failed to enable sensor calibration mode");
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
if (ret == OK) {
|
||||||
|
errx(0, "PASS");
|
||||||
|
} else {
|
||||||
|
errx(1, "FAIL");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset the driver.
|
* Reset the driver.
|
||||||
*/
|
*/
|
||||||
@@ -930,8 +1277,19 @@ hmc5883_main(int argc, char *argv[])
|
|||||||
/*
|
/*
|
||||||
* Print driver information.
|
* Print driver information.
|
||||||
*/
|
*/
|
||||||
if (!strcmp(argv[1], "info"))
|
if (!strcmp(argv[1], "info") || !strcmp(argv[1], "status"))
|
||||||
hmc5883::info();
|
hmc5883::info();
|
||||||
|
|
||||||
errx(1, "unrecognised command, try 'start', 'test', 'reset' or 'info'");
|
/*
|
||||||
|
* Autocalibrate the scaling
|
||||||
|
*/
|
||||||
|
if (!strcmp(argv[1], "calibrate")) {
|
||||||
|
if (hmc5883::calibrate() == 0) {
|
||||||
|
errx(0, "calibration successful");
|
||||||
|
} else {
|
||||||
|
errx(1, "calibration failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errx(1, "unrecognized command, try 'start', 'test', 'reset' 'calibrate' or 'info'");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -864,5 +864,5 @@ l3gd20_main(int argc, char *argv[])
|
|||||||
if (!strcmp(argv[1], "info"))
|
if (!strcmp(argv[1], "info"))
|
||||||
l3gd20::info();
|
l3gd20::info();
|
||||||
|
|
||||||
errx(1, "unrecognised command, try 'start', 'test', 'reset' or 'info'");
|
errx(1, "unrecognized command, try 'start', 'test', 'reset' or 'info'");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
############################################################################
|
||||||
|
#
|
||||||
|
# Copyright (C) 2012 PX4 Development Team. All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions
|
||||||
|
# are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in
|
||||||
|
# the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
# 3. Neither the name PX4 nor the names of its contributors may be
|
||||||
|
# used to endorse or promote products derived from this software
|
||||||
|
# without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
#
|
||||||
|
# Tone alarm driver
|
||||||
|
#
|
||||||
|
|
||||||
|
APPNAME = tone_alarm
|
||||||
|
PRIORITY = SCHED_PRIORITY_DEFAULT
|
||||||
|
STACKSIZE = 2048
|
||||||
|
INCLUDES = $(TOPDIR)/arch/arm/src/stm32 $(TOPDIR)/arch/arm/src/common
|
||||||
|
|
||||||
|
include $(APPDIR)/mk/app.mk
|
||||||
+243
-122
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (C) 2012 PX4 Development Team. All rights reserved.
|
* Copyright (C) 2012 PX4 Development Team. All rights reserved.
|
||||||
* Author: @author Ivan Ovinnikov <oivan@ethz.ch>
|
* Author: @author Ivan Ovinnikov <oivan@ethz.ch>
|
||||||
|
* Modifications: Doug Weibel <douglas.weibel@colorado.edu>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@@ -31,7 +32,7 @@
|
|||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
// Workflow test comment - DEW
|
|
||||||
/**
|
/**
|
||||||
* @file fixedwing_control.c
|
* @file fixedwing_control.c
|
||||||
* Implementation of a fixed wing attitude and position controller.
|
* Implementation of a fixed wing attitude and position controller.
|
||||||
@@ -86,27 +87,61 @@ static void usage(const char *reason);
|
|||||||
* Controller parameters, accessible via MAVLink
|
* Controller parameters, accessible via MAVLink
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
PARAM_DEFINE_FLOAT(FW_ROLL_POS_P, 0.3f);
|
// Roll control parameters
|
||||||
PARAM_DEFINE_FLOAT(FW_ROLL_POS_I, 0.002f);
|
PARAM_DEFINE_FLOAT(FW_ROLLRATE_P, 0.3f);
|
||||||
PARAM_DEFINE_FLOAT(FW_ROLL_POS_AWU, 0.2f);
|
// Need to add functionality to suppress integrator windup while on the ground
|
||||||
PARAM_DEFINE_FLOAT(FW_ROLL_POS_LIM, 0.6f);
|
// Suggested value of FW_ROLLRATE_I is 0.0 till this is in place
|
||||||
|
PARAM_DEFINE_FLOAT(FW_ROLLRATE_I, 0.0f);
|
||||||
|
PARAM_DEFINE_FLOAT(FW_ROLLRATE_AWU, 0.0f);
|
||||||
|
PARAM_DEFINE_FLOAT(FW_ROLLRATE_LIM, 0.7f); // Roll rate limit in radians/sec
|
||||||
|
PARAM_DEFINE_FLOAT(FW_ROLL_P, 0.3f);
|
||||||
|
PARAM_DEFINE_FLOAT(FW_ROLL_LIM, 0.7f); // Roll angle limit in radians
|
||||||
|
|
||||||
|
//Pitch control parameters
|
||||||
|
PARAM_DEFINE_FLOAT(FW_PITCHRATE_P, 0.3f);
|
||||||
|
// Need to add functionality to suppress integrator windup while on the ground
|
||||||
|
// Suggested value of FW_PITCHRATE_I is 0.0 till this is in place
|
||||||
|
PARAM_DEFINE_FLOAT(FW_PITCHRATE_I, 0.0f);
|
||||||
|
PARAM_DEFINE_FLOAT(FW_PITCHRATE_AWU, 0.0f);
|
||||||
|
PARAM_DEFINE_FLOAT(FW_PITCHRATE_LIM, 0.35f); // Pitch rate limit in radians/sec
|
||||||
|
PARAM_DEFINE_FLOAT(FW_PITCH_P, 0.3f);
|
||||||
|
PARAM_DEFINE_FLOAT(FW_PITCH_LIM, 0.35f); // Pitch angle limit in radians
|
||||||
|
|
||||||
struct fw_att_control_params {
|
struct fw_att_control_params {
|
||||||
float roll_pos_p;
|
float rollrate_p;
|
||||||
float roll_pos_i;
|
float rollrate_i;
|
||||||
float roll_pos_awu;
|
float rollrate_awu;
|
||||||
float roll_pos_lim;
|
float rollrate_lim;
|
||||||
|
float roll_p;
|
||||||
|
float roll_lim;
|
||||||
|
float pitchrate_p;
|
||||||
|
float pitchrate_i;
|
||||||
|
float pitchrate_awu;
|
||||||
|
float pitchrate_lim;
|
||||||
|
float pitch_p;
|
||||||
|
float pitch_lim;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fw_att_control_param_handles {
|
struct fw_att_control_param_handles {
|
||||||
param_t roll_pos_p;
|
param_t rollrate_p;
|
||||||
param_t roll_pos_i;
|
param_t rollrate_i;
|
||||||
param_t roll_pos_awu;
|
param_t rollrate_awu;
|
||||||
param_t roll_pos_lim;
|
param_t rollrate_lim;
|
||||||
|
param_t roll_p;
|
||||||
|
param_t roll_lim;
|
||||||
|
param_t pitchrate_p;
|
||||||
|
param_t pitchrate_i;
|
||||||
|
param_t pitchrate_awu;
|
||||||
|
param_t pitchrate_lim;
|
||||||
|
param_t pitch_p;
|
||||||
|
param_t pitch_lim;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// XXX outsource position control to a separate app some time
|
// TO_DO - Navigation control will be moved to a separate app
|
||||||
|
// Attitude control will just handle the inner angle and rate loops
|
||||||
|
// to control pitch and roll, and turn coordination via rudder and
|
||||||
|
// possibly throttle compensation for battery voltage sag.
|
||||||
|
|
||||||
PARAM_DEFINE_FLOAT(FW_HEADING_P, 0.1f);
|
PARAM_DEFINE_FLOAT(FW_HEADING_P, 0.1f);
|
||||||
PARAM_DEFINE_FLOAT(FW_HEADING_LIM, 0.15f);
|
PARAM_DEFINE_FLOAT(FW_HEADING_LIM, 0.15f);
|
||||||
@@ -147,9 +182,9 @@ static int pos_parameters_update(const struct fw_pos_control_param_handles *h, s
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The fixed wing control main loop.
|
* The fixed wing control main thread.
|
||||||
*
|
*
|
||||||
* This loop executes continously and calculates the control
|
* The main loop executes continously and calculates the control
|
||||||
* response.
|
* response.
|
||||||
*
|
*
|
||||||
* @param argc number of arguments
|
* @param argc number of arguments
|
||||||
@@ -223,19 +258,31 @@ int fixedwing_control_thread_main(int argc, char *argv[])
|
|||||||
pos_parameters_init(&hpos);
|
pos_parameters_init(&hpos);
|
||||||
pos_parameters_update(&hpos, &ppos);
|
pos_parameters_update(&hpos, &ppos);
|
||||||
|
|
||||||
PID_t roll_pos_controller;
|
// TO_DO Fix output limit functionallity of PID controller or add that function elsewhere
|
||||||
pid_init(&roll_pos_controller, p.roll_pos_p, p.roll_pos_i, 0.0f, p.roll_pos_awu,
|
PID_t roll_rate_controller;
|
||||||
PID_MODE_DERIVATIV_SET);
|
pid_init(&roll_rate_controller, p.rollrate_p, p.rollrate_i, 0.0f, p.rollrate_awu,
|
||||||
|
p.rollrate_lim,PID_MODE_DERIVATIV_NONE);
|
||||||
|
PID_t roll_angle_controller;
|
||||||
|
pid_init(&roll_angle_controller, p.roll_p, 0.0f, 0.0f, 0.0f,
|
||||||
|
p.roll_lim,PID_MODE_DERIVATIV_NONE);
|
||||||
|
|
||||||
|
PID_t pitch_rate_controller;
|
||||||
|
pid_init(&pitch_rate_controller, p.pitchrate_p, p.pitchrate_i, 0.0f, p.pitchrate_awu,
|
||||||
|
p.pitchrate_lim,PID_MODE_DERIVATIV_NONE);
|
||||||
|
PID_t pitch_angle_controller;
|
||||||
|
pid_init(&pitch_angle_controller, p.pitch_p, 0.0f, 0.0f, 0.0f,
|
||||||
|
p.pitch_lim,PID_MODE_DERIVATIV_NONE);
|
||||||
|
|
||||||
PID_t heading_controller;
|
PID_t heading_controller;
|
||||||
pid_init(&heading_controller, ppos.heading_p, 0.0f, 0.0f, 0.0f,
|
pid_init(&heading_controller, ppos.heading_p, 0.0f, 0.0f, 0.0f,
|
||||||
PID_MODE_DERIVATIV_SET);
|
100.0f,PID_MODE_DERIVATIV_SET); // Temporary arbitrarily large limit
|
||||||
|
|
||||||
// XXX remove in production
|
// XXX remove in production
|
||||||
/* advertise debug value */
|
/* advertise debug value */
|
||||||
struct debug_key_value_s dbg = { .key = "", .value = 0.0f };
|
struct debug_key_value_s dbg = { .key = "", .value = 0.0f };
|
||||||
orb_advert_t pub_dbg = orb_advertise(ORB_ID(debug_key_value), &dbg);
|
orb_advert_t pub_dbg = orb_advertise(ORB_ID(debug_key_value), &dbg);
|
||||||
|
|
||||||
|
// This is the top of the main loop
|
||||||
while(!thread_should_exit) {
|
while(!thread_should_exit) {
|
||||||
|
|
||||||
struct pollfd fds[1] = {
|
struct pollfd fds[1] = {
|
||||||
@@ -251,11 +298,20 @@ int fixedwing_control_thread_main(int argc, char *argv[])
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
// FIXME SUBSCRIBE
|
// FIXME SUBSCRIBE
|
||||||
if (loopcounter % 20 == 0) {
|
if (loopcounter % 100 == 0) {
|
||||||
att_parameters_update(&h, &p);
|
att_parameters_update(&h, &p);
|
||||||
pos_parameters_update(&hpos, &ppos);
|
pos_parameters_update(&hpos, &ppos);
|
||||||
pid_set_parameters(&roll_pos_controller, p.roll_pos_p, p.roll_pos_i, 0.0f, p.roll_pos_awu);
|
pid_set_parameters(&roll_rate_controller, p.rollrate_p, p.rollrate_i, 0.0f,
|
||||||
pid_set_parameters(&heading_controller, ppos.heading_p, 0.0f, 0.0f, 0.0f);
|
p.rollrate_awu, p.rollrate_lim);
|
||||||
|
pid_set_parameters(&roll_angle_controller, p.roll_p, 0.0f, 0.0f,
|
||||||
|
0.0f, p.roll_lim);
|
||||||
|
pid_set_parameters(&pitch_rate_controller, p.pitchrate_p, p.pitchrate_i, 0.0f,
|
||||||
|
p.pitchrate_awu, p.pitchrate_lim);
|
||||||
|
pid_set_parameters(&pitch_angle_controller, p.pitch_p, 0.0f, 0.0f,
|
||||||
|
0.0f, p.pitch_lim);
|
||||||
|
pid_set_parameters(&heading_controller, ppos.heading_p, 0.0f, 0.0f, 0.0f, 90.0f);
|
||||||
|
//printf("[fixedwing control debug] p: %8.4f, i: %8.4f, limit: %8.4f \n",
|
||||||
|
//p.rollrate_p, p.rollrate_i, p.rollrate_lim);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if position updated, run position control loop */
|
/* if position updated, run position control loop */
|
||||||
@@ -359,14 +415,25 @@ int fixedwing_control_thread_main(int argc, char *argv[])
|
|||||||
printf("[fixedwing control] roll sp: %8.4f, \n", att_sp.roll_body);
|
printf("[fixedwing control] roll sp: %8.4f, \n", att_sp.roll_body);
|
||||||
}
|
}
|
||||||
|
|
||||||
// actuators.control[0] = pid_calculate(&roll_pos_controller, att_sp.roll_body,
|
// actuator control[0] is aileron (or elevon roll control)
|
||||||
// att.roll, att.rollspeed, deltaTpos);
|
// Commanded roll rate from P controller on roll angle
|
||||||
actuators.control[0] = pid_calculate(&roll_pos_controller, att_sp.roll_body,
|
float roll_rate_command = pid_calculate(&roll_angle_controller, att_sp.roll_body,
|
||||||
att.roll, att.rollspeed, deltaTpos);
|
att.roll, 0.0f, deltaTpos);
|
||||||
actuators.control[1] = 0;
|
// actuator control from PI controller on roll rate
|
||||||
actuators.control[2] = 0;
|
actuators.control[0] = pid_calculate(&roll_rate_controller, roll_rate_command,
|
||||||
|
att.rollspeed, 0.0f, deltaTpos);
|
||||||
|
|
||||||
|
// actuator control[1] is elevator (or elevon pitch control)
|
||||||
|
// Commanded pitch rate from P controller on pitch angle
|
||||||
|
float pitch_rate_command = pid_calculate(&pitch_angle_controller, att_sp.pitch_body,
|
||||||
|
att.pitch, 0.0f, deltaTpos);
|
||||||
|
// actuator control from PI controller on pitch rate
|
||||||
|
actuators.control[1] = pid_calculate(&pitch_rate_controller, pitch_rate_command,
|
||||||
|
att.pitchspeed, 0.0f, deltaTpos);
|
||||||
|
|
||||||
|
// actuator control[3] is throttle
|
||||||
actuators.control[3] = att_sp.thrust;
|
actuators.control[3] = att_sp.thrust;
|
||||||
|
|
||||||
/* publish attitude setpoint (for MAVLink) */
|
/* publish attitude setpoint (for MAVLink) */
|
||||||
orb_publish(ORB_ID(vehicle_attitude_setpoint), att_sp_pub, &att_sp);
|
orb_publish(ORB_ID(vehicle_attitude_setpoint), att_sp_pub, &att_sp);
|
||||||
|
|
||||||
@@ -446,21 +513,38 @@ int fixedwing_control_main(int argc, char *argv[])
|
|||||||
static int att_parameters_init(struct fw_att_control_param_handles *h)
|
static int att_parameters_init(struct fw_att_control_param_handles *h)
|
||||||
{
|
{
|
||||||
/* PID parameters */
|
/* PID parameters */
|
||||||
h->roll_pos_p = param_find("FW_ROLL_POS_P");
|
|
||||||
h->roll_pos_i = param_find("FW_ROLL_POS_I");
|
h->rollrate_p = param_find("FW_ROLLRATE_P");
|
||||||
h->roll_pos_lim = param_find("FW_ROLL_POS_LIM");
|
h->rollrate_i = param_find("FW_ROLLRATE_I");
|
||||||
h->roll_pos_awu = param_find("FW_ROLL_POS_AWU");
|
h->rollrate_awu = param_find("FW_ROLLRATE_AWU");
|
||||||
|
h->rollrate_lim = param_find("FW_ROLLRATE_LIM");
|
||||||
|
h->roll_p = param_find("FW_ROLL_P");
|
||||||
|
h->roll_lim = param_find("FW_ROLL_LIM");
|
||||||
|
h->pitchrate_p = param_find("FW_PITCHRATE_P");
|
||||||
|
h->pitchrate_i = param_find("FW_PITCHRATE_I");
|
||||||
|
h->pitchrate_awu = param_find("FW_PITCHRATE_AWU");
|
||||||
|
h->pitchrate_lim = param_find("FW_PITCHRATE_LIM");
|
||||||
|
h->pitch_p = param_find("FW_PITCH_P");
|
||||||
|
h->pitch_lim = param_find("FW_PITCH_LIM");
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int att_parameters_update(const struct fw_att_control_param_handles *h, struct fw_att_control_params *p)
|
static int att_parameters_update(const struct fw_att_control_param_handles *h, struct fw_att_control_params *p)
|
||||||
{
|
{
|
||||||
param_get(h->roll_pos_p, &(p->roll_pos_p));
|
param_get(h->rollrate_p, &(p->rollrate_p));
|
||||||
param_get(h->roll_pos_i, &(p->roll_pos_i));
|
param_get(h->rollrate_i, &(p->rollrate_i));
|
||||||
param_get(h->roll_pos_lim, &(p->roll_pos_lim));
|
param_get(h->rollrate_awu, &(p->rollrate_awu));
|
||||||
param_get(h->roll_pos_awu, &(p->roll_pos_awu));
|
param_get(h->rollrate_lim, &(p->rollrate_lim));
|
||||||
|
param_get(h->roll_p, &(p->roll_p));
|
||||||
|
param_get(h->roll_lim, &(p->roll_lim));
|
||||||
|
param_get(h->pitchrate_p, &(p->pitchrate_p));
|
||||||
|
param_get(h->pitchrate_i, &(p->pitchrate_i));
|
||||||
|
param_get(h->pitchrate_awu, &(p->pitchrate_awu));
|
||||||
|
param_get(h->pitchrate_lim, &(p->pitchrate_lim));
|
||||||
|
param_get(h->pitch_p, &(p->pitch_p));
|
||||||
|
param_get(h->pitch_lim, &(p->pitch_lim));
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user