72 _sample_buffer(nullptr)
375 _samples_collected --;
402 static const float a = (4.0f *
M_PI / (3.0f * faces)) +
M_PI / 3.0f;
403 static const float theta = 0.5f * acosf(cosf(a) / (1.0
f - cosf(a)));
413 if(distance < min_distance) {
430 return params.
radius - (softiron*(sample+params.
offset)).length();
458 diag.
x , offdiag.
x , offdiag.
y,
459 offdiag.
x , diag.
y , offdiag.
z,
460 offdiag.
y , offdiag.
z , diag.
z 463 float A = (diag.
x * (sample.
x + offset.
x)) + (offdiag.
x * (sample.
y + offset.
y)) + (offdiag.
y * (sample.
z + offset.
z));
464 float B = (offdiag.
x * (sample.
x + offset.
x)) + (diag.
y * (sample.
y + offset.
y)) + (offdiag.
z * (sample.
z + offset.
z));
465 float C = (offdiag.
y * (sample.
x + offset.
x)) + (offdiag.
z * (sample.
y + offset.
y)) + (diag.
z * (sample.
z + offset.
z));
466 float length = (softiron*(sample+
offset)).length();
471 ret[1] = -1.0f * (((diag.
x * A) + (offdiag.
x * B) + (offdiag.
y * C))/length);
472 ret[2] = -1.0f * (((offdiag.
x * A) + (diag.
y * B) + (offdiag.
z * C))/length);
473 ret[3] = -1.0f * (((offdiag.
y * A) + (offdiag.
z * B) + (diag.
z * C))/length);
492 const float lma_damping = 10.0f;
496 param_t fit1_params, fit2_params;
497 fit1_params = fit2_params =
_params;
514 JTJ[i*COMPASS_CAL_NUM_SPHERE_PARAMS+j] += sphere_jacob[i] * sphere_jacob[j];
515 JTJ2[i*COMPASS_CAL_NUM_SPHERE_PARAMS+j] += sphere_jacob[i] * sphere_jacob[j];
518 JTFI[i] += sphere_jacob[i] *
calc_residual(sample, fit1_params);
527 JTJ2[i*COMPASS_CAL_NUM_SPHERE_PARAMS+i] +=
_sphere_lambda/lma_damping;
540 fit1_params.
get_sphere_params()[row] -= JTFI[col] * JTJ[row*COMPASS_CAL_NUM_SPHERE_PARAMS+col];
541 fit2_params.
get_sphere_params()[row] -= JTFI[col] * JTJ2[row*COMPASS_CAL_NUM_SPHERE_PARAMS+col];
550 }
else if(fit2 <
_fitness && fit2 < fit1) {
552 fit1_params = fit2_params;
559 if(!isnan(fitness) && fitness <
_fitness) {
573 diag.
x , offdiag.
x , offdiag.
y,
574 offdiag.
x , diag.
y , offdiag.
z,
575 offdiag.
y , offdiag.
z , diag.
z 578 float A = (diag.
x * (sample.
x + offset.
x)) + (offdiag.
x * (sample.
y + offset.
y)) + (offdiag.
y * (sample.
z + offset.
z));
579 float B = (offdiag.
x * (sample.
x + offset.
x)) + (diag.
y * (sample.
y + offset.
y)) + (offdiag.
z * (sample.
z + offset.
z));
580 float C = (offdiag.
y * (sample.
x + offset.
x)) + (offdiag.
z * (sample.
y + offset.
y)) + (diag.
z * (sample.
z + offset.
z));
581 float length = (softiron*(sample+
offset)).length();
584 ret[0] = -1.0f * (((diag.
x * A) + (offdiag.
x * B) + (offdiag.
y * C))/length);
585 ret[1] = -1.0f * (((offdiag.
x * A) + (diag.
y * B) + (offdiag.
z * C))/length);
586 ret[2] = -1.0f * (((offdiag.
y * A) + (offdiag.
z * B) + (diag.
z * C))/length);
588 ret[3] = -1.0f * ((sample.
x + offset.
x) * A)/length;
589 ret[4] = -1.0f * ((sample.
y + offset.
y) * B)/length;
590 ret[5] = -1.0f * ((sample.
z + offset.
z) * C)/length;
592 ret[6] = -1.0f * (((sample.
y + offset.
y) * A) + ((sample.
x + offset.
x) * B))/length;
593 ret[7] = -1.0f * (((sample.
z + offset.
z) * A) + ((sample.
x + offset.
x) * C))/length;
594 ret[8] = -1.0f * (((sample.
z + offset.
z) * B) + ((sample.
y + offset.
y) * C))/length;
603 const float lma_damping = 10.0f;
608 param_t fit1_params, fit2_params;
609 fit1_params = fit2_params =
_params;
627 JTJ [i*COMPASS_CAL_NUM_ELLIPSOID_PARAMS+j] += ellipsoid_jacob[i] * ellipsoid_jacob[j];
628 JTJ2[i*COMPASS_CAL_NUM_ELLIPSOID_PARAMS+j] += ellipsoid_jacob[i] * ellipsoid_jacob[j];
631 JTFI[i] += ellipsoid_jacob[i] *
calc_residual(sample, fit1_params);
654 fit1_params.
get_ellipsoid_params()[row] -= JTFI[col] * JTJ[row*COMPASS_CAL_NUM_ELLIPSOID_PARAMS+col];
655 fit2_params.
get_ellipsoid_params()[row] -= JTFI[col] * JTJ2[row*COMPASS_CAL_NUM_ELLIPSOID_PARAMS+col];
664 }
else if(fit2 <
_fitness && fit2 < fit1) {
666 fit1_params = fit2_params;
685 #define COMPASS_CAL_SAMPLE_SCALE_TO_FIXED(__X) ((int16_t)constrain_float(roundf(__X*8.0f), INT16_MIN, INT16_MAX)) 686 #define COMPASS_CAL_SAMPLE_SCALE_TO_FLOAT(__X) (__X/8.0f) float get_completion_percent() const
void start(bool retry, float delay, uint16_t offset_max)
void new_sample(const Vector3f &sample)
Vector3< float > Vector3f
enum compass_cal_status_t _status
float calc_residual(const Vector3f &sample, const param_t ¶ms) const
#define COMPASS_CAL_SAMPLE_SCALE_TO_FLOAT(__X)
void calc_ellipsoid_jacob(const Vector3f &sample, const param_t ¶ms, float *ret) const
void update_completion_mask()
uint8_t completion_mask_t[10]
#define COMPASS_CAL_NUM_ELLIPSOID_PARAMS
completion_mask_t _completion_mask
completion_mask_t & get_completion_mask()
void calc_sphere_jacob(const Vector3f &sample, const param_t ¶ms, float *ret) const
void * calloc(size_t nmemb, size_t size)
float * get_sphere_params()
uint16_t get_random16(void)
void update(bool &failure)
uint16_t _samples_collected
uint16_t _samples_thinned
void get_calibration(Vector3f &offsets, Vector3f &diagonals, Vector3f &offdiagonals)
void set(const Vector3f &in)
#define COMPASS_CAL_NUM_SPHERE_PARAMS
bool set_status(compass_cal_status_t status)
bool accept_sample(const Vector3f &sample)
#define COMPASS_CAL_SAMPLE_SCALE_TO_FIXED(__X)
float * get_ellipsoid_params()
#define COMPASS_CAL_NUM_SAMPLES
std::enable_if< std::is_integral< typename std::common_type< Arithmetic1, Arithmetic2 >::type >::value,bool >::type is_equal(const Arithmetic1 v_1, const Arithmetic2 v_2)
static int section(const Vector3f &v, bool inclusive=false)
#define COMPASS_CAL_DEFAULT_TOLERANCE
void calc_initial_offset()
bool inverse(float x[], float y[], uint16_t dim)
float calc_mean_squared_residuals() const
CompassSample * _sample_buffer