-
-
Notifications
You must be signed in to change notification settings - Fork 19
Open
Labels
enhancementNew feature or requestNew feature or requestsweepAssigns Sweep to an issue or pull request.Assigns Sweep to an issue or pull request.
Description
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:
Drawbacks
- The approach above requires applying a custom filter to the sensor.
Unresolved questions
No response
sweep-ai-deprecated
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or requestsweepAssigns Sweep to an issue or pull request.Assigns Sweep to an issue or pull request.