diff options
| author | Stanislaw Halik <sthalik@misaki.pl> | 2018-03-05 20:39:58 +0100 | 
|---|---|---|
| committer | Stanislaw Halik <sthalik@misaki.pl> | 2018-03-10 18:35:13 +0100 | 
| commit | 1384338acf910ec15d98aec44eca0c45028ce008 (patch) | |
| tree | 9b72e5c83682aeb0483c6e808e5cb2e46b0182a3 | |
| parent | 4fa5cac95f24732b3e4362561491b3e63737200a (diff) | |
Revert "compat/correlation-calibration: retire"
This reverts commit
7cf79b12ddbfeedf24861ff489a1008f867d9440.
| -rw-r--r-- | compat/correlation-calibrator.cpp | 166 | ||||
| -rw-r--r-- | compat/correlation-calibrator.hpp | 76 | 
2 files changed, 242 insertions, 0 deletions
| diff --git a/compat/correlation-calibrator.cpp b/compat/correlation-calibrator.cpp new file mode 100644 index 00000000..aef804d2 --- /dev/null +++ b/compat/correlation-calibrator.cpp @@ -0,0 +1,166 @@ +#include "correlation-calibrator.hpp" +#include "variance.hpp" +#include "compat/math.hpp" + +#include <cmath> +#include <iterator> + +#include <QDebug> + +#define DEBUG_PRINT +#ifdef DEBUG_PRINT +#   include <cstdio> +#   include <cwchar> +    using std::fwprintf; +    using std::fflush; +#endif + +using namespace correlation_calibrator_impl; + +correlation_calibrator::correlation_calibrator() +{ +} + +static constexpr unsigned nbuckets[6] = +{ +    x_nbuckets, +    y_nbuckets, +    z_nbuckets, + +    yaw_nbuckets, +    pitch_nbuckets, +    roll_nbuckets, +}; + +static constexpr double spacing[6] = +{ +    translation_spacing, +    translation_spacing, +    translation_spacing, + +    yaw_spacing_in_degrees, +    pitch_spacing_in_degrees, +    roll_spacing_in_degrees, +}; + +static constexpr wchar_t const* const names[6] { +    L"x", L"y", L"z", +    L"yaw", L"pitch", L"roll", +}; + +bool correlation_calibrator::check_buckets(const vec6 &data) +{ +    bool ret = false; +    unsigned pos[6]; + +    for (unsigned k = 0; k < 6; k++) +    { +        const double val = clamp(data[k], min[k], max[k]); +        pos[k] = (val-min[k])/spacing[k]; + +        if (pos[k] >= nbuckets[k]) +        { +            qDebug() << "idx" << k +                     << "bucket" << (int)pos[k] +                     << "outside bounds" << nbuckets[k]; + +            return false; +        } + +        if (!buckets[k][pos[k]]) +            ret = true; + +        buckets[k][pos[k]] = true; +    } + +    if (ret) +        for (unsigned k = 0; k < 6; k++) +            buckets[k][pos[k]] = true; + +    return ret; +} + +void correlation_calibrator::input(const vec6& data_) +{ +    if (!check_buckets(data_)) +        return; + +    data.push_back(data_); +} + +mat66 correlation_calibrator::get_coefficients() const +{ +    if (data.size() < min_samples) +    { +        qDebug() << "correlation-calibrator: not enough data"; + +        mat66 ret; +        for (unsigned k = 0; k < 6; k++) +            ret(k, k) = 1; +        return ret; +    } + +    variance vs[6]; +    vec6 devs, means; + +    for (const vec6& x : data) +        for (unsigned i = 0; i < 6; i++) +            vs[i].input(x(i)); + +    for (unsigned i = 0; i < 6; i++) +    { +        means(i) = vs[i].avg(); +        devs(i) = vs[i].stddev(); + +        constexpr double EPS = 1e-4; + +        if (devs(i) < EPS) +            devs(i) = EPS; +    } + +    mat66 cs; + +    for (const vec6& x : data) +        for (unsigned k = 0; k < 6; k++) +        { +            for (unsigned idx = 0; idx < 6; idx++) +            { +                const double zi = (x(idx) - means(idx)), +                             zk = (x(k) - means(k)); + +                cs(idx, k) += zi * zk / (devs(k)*devs(k)); +            } +        } + +    cs = cs * (1./(data.size() - 1)); + +#if defined DEBUG_PRINT +    fwprintf(stderr, L"v:change-of h:due-to\n"); +    fwprintf(stderr, L"%10s ", L""); +    for (unsigned k = 0; k < 6; k++) +        fwprintf(stderr, L"%10s", names[k]); +    fwprintf(stderr, L"\n"); + +    for (unsigned i = 0; i < 6; i++) +    { +        fwprintf(stderr, L"%10s ", names[i]); +        for (unsigned k = 0; k < 6; k++) +            fwprintf(stderr, L"%10.3f", cs(i, k)); +        fwprintf(stderr, L"\n"); +    } +    fflush(stderr); +#endif + +    for (unsigned k = 0; k < 6; k++) +        cs(k, k) = 1; + +    // derivations from +    // https://www.thoughtco.com/how-to-calculate-the-correlation-coefficient-3126228 + +    return cs; +} + +unsigned correlation_calibrator::sample_count() const +{ +    return data.size(); +} diff --git a/compat/correlation-calibrator.hpp b/compat/correlation-calibrator.hpp new file mode 100644 index 00000000..b44a2312 --- /dev/null +++ b/compat/correlation-calibrator.hpp @@ -0,0 +1,76 @@ +#pragma once + +#include "simple-mat.hpp" +#include <array> +#include <vector> +#include <tuple> + +#include "export.hpp" + +namespace correlation_calibrator_impl { + +static constexpr inline double min[6] = { +    -50, +    -50, +    250, + +    -180, +    -180, +    -180, +}; + +static constexpr inline double max[6] = { +    50, +    50, +    250, + +    180, +    180, +    180, +}; + +static constexpr inline double yaw_spacing_in_degrees = 1.5; +static constexpr inline double pitch_spacing_in_degrees = 1; +static constexpr inline double roll_spacing_in_degrees = 1; + +static constexpr inline unsigned yaw_nbuckets   = 1+ 360./yaw_spacing_in_degrees; +static constexpr inline unsigned pitch_nbuckets = 1+ 360./pitch_spacing_in_degrees; +static constexpr inline unsigned roll_nbuckets  = 1+ 360./roll_spacing_in_degrees; + +static constexpr inline double translation_spacing = .25; +static constexpr inline unsigned x_nbuckets = 1+ (max[0]-min[0])/translation_spacing; +static constexpr inline unsigned y_nbuckets = 1+ (max[1]-min[1])/translation_spacing; +static constexpr inline unsigned z_nbuckets = 1+ (max[2]-min[2])/translation_spacing; + +using vec6 = Mat<double, 6, 1>; +using mat66 = Mat<double, 6, 6>; + +class OTR_COMPAT_EXPORT correlation_calibrator final +{ +    // careful to avoid vector copies +    std::array<std::vector<bool>, 6> buckets = +    { +        std::vector<bool>(x_nbuckets,       false), +        std::vector<bool>(y_nbuckets,       false), +        std::vector<bool>(z_nbuckets,       false), +        std::vector<bool>(yaw_nbuckets,     false), +        std::vector<bool>(pitch_nbuckets,   false), +        std::vector<bool>(roll_nbuckets,    false), +    }; + +    std::vector<vec6> data; + +    bool check_buckets(const vec6& data); + +public: +    correlation_calibrator(); +    void input(const vec6& data); +    mat66 get_coefficients() const; +    unsigned sample_count() const; + +    static constexpr inline unsigned min_samples = 25; +}; + +} // ns correlation_calibrator_impl + +using correlation_calibrator_impl::correlation_calibrator; | 
