22static constexpr uint8_t X_AXIS = 0;
23static constexpr uint8_t Y_AXIS = 1;
24static constexpr uint8_t Z_AXIS = 2;
34 float ax = data.acceleration[X_AXIS];
35 float ay = data.acceleration[Y_AXIS];
36 float az = data.acceleration[Z_AXIS];
37 if (std::isnan(ax) || std::isnan(ay) || std::isnan(az))
39 float mag = std::sqrt(ax * ax + ay * ay + az * az);
43 float h = std::sqrt(ax * ax + ay * ay);
44 if (
h / mag < flat_threshold)
47 float angle = std::atan2(ay, ax) * (180.0f / std::numbers::pi_v<float>);
48 int quadrant =
static_cast<int>(std::lround(angle / 90.0f));
49 quadrant = ((quadrant % 4) + 4) % 4;
50 return quadrant * 90.0f;
65 void setup()
override;
70 memcpy(this->
base_matrix_, m.data(),
sizeof(this->base_matrix_));
71 memcpy(this->
matrix_, m.data(),
sizeof(this->matrix_));
93 1, 0, 0, 0, 1, 0, 0, 0, 1,
98 1, 0, 0, 0, 1, 0, 0, 0, 1,
101 void map_axes_(
float output[3],
const float input[3])
const {
102 output[0] = input[X_AXIS] * this->
matrix_[0] + input[Y_AXIS] * this->
matrix_[1] + input[Z_AXIS] * this->
matrix_[2];
103 output[1] = input[X_AXIS] * this->matrix_[3] + input[Y_AXIS] * this->matrix_[4] + input[Z_AXIS] * this->matrix_[5];
104 output[2] = input[X_AXIS] * this->matrix_[6] + input[Y_AXIS] * this->matrix_[7] + input[Z_AXIS] * this->matrix_[8];
123 void play(
const Ts &...)
override {
148 void play(
const Ts &...)
override {
This class simplifies creating components that periodically check a state.
void trigger(const Ts &...x) ESPHOME_ALWAYS_INLINE
Inform the parent automation that the event has triggered.
Trigger * get_error_trigger()
CalibrateHeadingAction(MotionComponent *parent)
Trigger * get_success_trigger()
void play(const Ts &...) override
MotionComponent * parent_
CalibrateLevelAction(MotionComponent *parent)
void play(const Ts &...) override
Trigger * get_error_trigger()
MotionComponent * parent_
Trigger * get_success_trigger()
void map_axes_(float output[3], const float input[3]) const
void set_calibration_key(uint32_t key)
ESPPreferenceObject pref_
void add_listener(F &&cb)
bool calibrate_heading()
Assuming Y-axis rotation only, correct the heading so X/Y align correctly.
LazyCallbackManager< void(MotionData const &)> motion_data_callback_
void set_matrix(const std::array< float, 9 > &m)
virtual bool update_data(MotionData &data)=0
bool calibrate_level()
Calibrate the matrix so the current reading maps to [0, 0, 1] (device flat).
void dump_config() override
void clear_calibration(bool save=false)
Restore the build-time (axis_map / transform_matrix) base, discarding calibration,...
bool save_calibration()
Save the current matrix to NVS.
float orientation_degrees(const MotionData &data, float flat_threshold)
Compute the device's in-plane orientation from the gravity vector.
struct esphome::motion::CalibrationPref PACKED