Skip to content

[Request]: atan2 sensor #104

@leon0399

Description

@leon0399

Implementation PR

No response

Reference Issues

No response

Summary

Create a new sensor that utilizes the atan2 function to calculate the angle from two analog inputs: cos and sin

Basic Example

auto* sin_sensor = new AnalogSensor(PIN_SIN);
auto* cos_sensor = new AnalogSensor(PIN_COS);

// (0.0F, 1.0F) => (-1.0F, 1.0F)
auto* sincos_filter = new LambdaFilter<float>([](float value) {
    return value * 2.0F - 1.0F;
});

sin_sensor->addFilter(sincos_filter);
cos_sensor->addFilter(sincos_filter);

atan2_sensor = new Atan2Sensor(sin_sensor, cos_sensor);
/// Sensor that calculates the atan2 of two sensors
template<typename Tp = float>
class Atan2Sensor : public Sensor<Tp> {
    static_assert(std::is_floating_point_v<Tp>, "Tp must be a floating point type");

  public:
    using Source = Sensor<Tp>;

    Atan2Sensor(Source* sin, Source* cos) : sin_(sin), cos_(cos){};

    void init() override
    {
        SS_SUBSENSOR_INIT(this->sin_, false, [this](float /*value*/) {
            this->recalculateState();
        });

        SS_SUBSENSOR_INIT(this->cos_, false, [this](float /*value*/) {
            this->recalculateState();
        });
    }

    inline void tick() override { this->recalculateState(); }

    void recalculateState()
    {
        const Tp sin = this->sin_->getValue();
        const Tp cos = this->cos_->getValue();

        if (sin == 0.0F && cos == 0.0F) {
            this->publishState(0.0F);
            return;
        }

        const Tp radians = std::atan2(sin, cos);

        this->publishState(radians);
    }

  private:
    Source* sin_;
    Source* cos_;
};

More examples:

  1. https://github.com/LucidVR/lucidgloves/blob/proto5/firmware/lucidgloves-firmware/input.ino#L315

Drawbacks

  1. The approach above requires applying a custom filter to the sensor.

Unresolved questions

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestsweepAssigns Sweep to an issue or pull request.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions