Skip to content

Commit

Permalink
feat(joystick): better support for circular joysticks
Browse files Browse the repository at this point in the history
* Refactored joystick so that the difference between RECTANGULAR and CIRCULAR joysticks is clearer and more completely applied
* Fixed not clamping output to be within the unit circle if the joystick is CIRCULAR
* Updated RangeMapper component to support individually setting the deadband value (around the input center)
* Update joystick to set x/y range mapper deadbands to 0 if configured as a CIRCULAR joystick so that only the center_deadzone_radius is applied
* rebuild docs
  • Loading branch information
finger563 committed Mar 1, 2024
1 parent ddf99a5 commit 73d80fa
Show file tree
Hide file tree
Showing 101 changed files with 370 additions and 277 deletions.
4 changes: 2 additions & 2 deletions components/joystick/example/main/joystick_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ extern "C" void app_main(void) {
// convert [0, 3300]mV to approximately [-1.0f, 1.0f]
.x_calibration = {.center = 1700.0f, .deadband = 0.0f, .minimum = 0.0f, .maximum = 3300.0f},
.y_calibration = {.center = 1700.0f, .deadband = 0.0f, .minimum = 0.0f, .maximum = 3300.0f},
.deadzone = espp::Joystick::Deadzone::CIRCULAR,
.deadzone_radius = 0.1f,
.type = espp::Joystick::Type::CIRCULAR,
.center_deadzone_radius = 0.1f,
.get_values = read_joystick,
});
auto task_fn = [&js1, &js2](std::mutex &m, std::condition_variable &cv) {
Expand Down
113 changes: 74 additions & 39 deletions components/joystick/include/joystick.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,19 @@ namespace espp {
class Joystick : public BaseComponent {
public:
/**
* @brief Types of deadzones the joystick can have.
* @note When using a Deadzone::CIRCULAR deadzone, it's recommended to set
* the individual x/y deadzones to be 0 and to only use the
* deadzone_radius field to set the deadzone.
* @brief Type of the joystick.
* @note When using a Type::CIRCULAR joystick, it's recommended to set the
* individual x/y calibration deadzones to be 0 and to only use the
* deadzone_radius field to set the deadzone around the center.
*/
enum class Deadzone {
RECTANGULAR, ///< Independent deadzones for the x and y axes utilizing a RangeMapper for each
///< axis.
CIRCULAR, ///< Coupled deadzone for both x and y axes. Still uses the rangemappers for each axis
///< (to convert raw values from input range to be [-1,1]) but applies a
///< circularization & circular deadzone after the conversion. @note With this
///< configuration, it is recommended to set the deadzones for each axis to be 0.
enum class Type {
RECTANGULAR, ///< The default type of joystick. Uses the rangemappers for
/// each axis (to convert raw values from input range to be
/// [-1,1]) independently which results in x/y deadzones and
/// output that are rectangular.
CIRCULAR, ///< The joystick is configured to have a circular output. This
/// means that the x/y < deadzones are circular around the input
/// and the output is clamped to be on or within the unit circle.
};

/**
Expand All @@ -44,12 +45,13 @@ class Joystick : public BaseComponent {
* @brief Configuration structure for the joystick.
*/
struct Config {
FloatRangeMapper::Config x_calibration; /**< Configuration for the x axis. */
FloatRangeMapper::Config y_calibration; /**< Configuration for the y axis. */
Deadzone deadzone{Deadzone::RECTANGULAR}; /**< The type of deadzone the joystick should use. See
Deadzone structure for more information. */
float deadzone_radius{0}; /**< The radius of the unit circle's deadzone [0, 1.0f], only used
when the joystick is configured with Deadzone::CIRCULAR. */
FloatRangeMapper::Config x_calibration; /**< Configuration for the x axis. */
FloatRangeMapper::Config y_calibration; /**< Configuration for the y axis. */
Type type{Type::RECTANGULAR}; /**< The type of the joystick. See Type enum
for more information. */
float center_deadzone_radius{
0}; /**< The radius of the unit circle's deadzone [0, 1.0f] around the center, only used
when the joystick is configured as Type::CIRCULAR. */
get_values_fn
get_values; /**< Function to retrieve the latest unmapped joystick values (range [-1,1]). */
Logger::Verbosity log_level{
Expand All @@ -64,35 +66,64 @@ class Joystick : public BaseComponent {
: BaseComponent("Joystick", config.log_level)
, x_mapper_(config.x_calibration)
, y_mapper_(config.y_calibration)
, deadzone_(config.deadzone)
, deadzone_radius_(config.deadzone_radius)
, type_(config.type)
, center_deadzone_radius_(config.center_deadzone_radius)
, get_values_(config.get_values) {}

/**
* @brief Sets the deadzone type and radius.
* @brief Set the type of the joystick.
* @param type The Type of the joystick.
* @param radius Optional radius parameter used when \p type is
* Type::CIRCULAR. When the magnitude of the joystick's mapped
* position vector is less than this value, the vector is set to
* (0,0).
* @note If the Joystick is Type::CIRCULAR, the actual calibrations that are
* saved into the joystick will have 0 deadzone around the center
* value, so that only the center deadzone radius is applied.
* @sa set_center_deadzone_radius
* @sa set_calibration
*/
void set_type(Type type, float radius = 0) {
type_ = type;
if (type_ == Type::CIRCULAR) {
x_mapper_.set_deadband(0);
y_mapper_.set_deadband(0);
}
center_deadzone_radius_ = radius;
}

/**
* @brief Sets the center deadzone radius.
* @note Radius is only applied when \p deadzone is Deadzone::CIRCULAR.
* @note Radius <= 0 means no additional deadzone is applied regardless of
* deadzone type.
* @param deadzone The Deadzone type to use with this joystick.
* @param radius Optional radius parameter used when \p deadzone is
* Deadzone::CIRCULAR. When the magnitude of the joystick's mapped
* position vector is less than this value, the vector is set to
* (0,0).
*/
void set_deadzone(Deadzone deadzone, float radius = 0) {
deadzone_ = deadzone;
deadzone_radius_ = radius;
}
void set_center_deadzone_radius(float radius) { center_deadzone_radius_ = radius; }

/**
* @brief Update the x and y axis mapping.
* @param x_calibration New x-axis range mapping configuration to use.
* @param y_calibration New y-axis range mapping configuration to use.
* @param center_deadzone_radius The radius of the unit circle's deadzone [0,
* 1.0f] around the center, only used when the joystick is configured
* as Type::CIRCULAR.
* @note If the Joystick is Type::CIRCULAR, the actual calibrations that are
* saved into the joystick will have 0 deadzone around the center value,
* so that only the center deadzone radius is applied.
* @sa set_center_deadzone_radius
*/
void set_calibration(const FloatRangeMapper::Config &x_calibration,
const FloatRangeMapper::Config &y_calibration) {
const FloatRangeMapper::Config &y_calibration,
float center_deadzone_radius = 0) {
x_mapper_.configure(x_calibration);
y_mapper_.configure(y_calibration);
if (type_ == Type::CIRCULAR) {
x_mapper_.set_deadband(0);
y_mapper_.set_deadband(0);
}
center_deadzone_radius_ = center_deadzone_radius;
}

/**
Expand All @@ -116,13 +147,17 @@ class Joystick : public BaseComponent {
raw_.y(_y);
position_.x(x_mapper_.map(_x));
position_.y(y_mapper_.map(_y));
// if we're configured to use a circular deadzone, then we apply a
// circular deadzone on the vector.
if (deadzone_ == Deadzone::CIRCULAR) {
if (position_.magnitude() < deadzone_radius_) {
// if we're configured to be a Type::CIRCULAR joystick, use the center
// deadzone radius and clamp the output to be within the unit circle
if (type_ == Type::CIRCULAR) {
auto magnitude = position_.magnitude();
if (magnitude < center_deadzone_radius_) {
// if it's within the deadzone radius, then set both axes to 0.
position_.x(0);
position_.y(0);
} else if (magnitude > 1.0f) {
// otherwise, we need to clamp the vector to be within the unit circle
position_ = position_.normalized();
}
}
}
Expand Down Expand Up @@ -160,13 +195,13 @@ class Joystick : public BaseComponent {
friend struct fmt::formatter<Joystick>;

protected:
Vector2f raw_;
Vector2f position_;
FloatRangeMapper x_mapper_;
FloatRangeMapper y_mapper_;
Deadzone deadzone_;
float deadzone_radius_;
get_values_fn get_values_;
Vector2f raw_{};
Vector2f position_{};
FloatRangeMapper x_mapper_{};
FloatRangeMapper y_mapper_{};
Type type_{Type::RECTANGULAR};
float center_deadzone_radius_{0};
get_values_fn get_values_{nullptr};
};
} // namespace espp

Expand Down
9 changes: 9 additions & 0 deletions components/math/include/range_mapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,15 @@ template <typename T> class RangeMapper {
*/
T get_output_max() const { return output_max_; }

/**
* @brief Set the deadband for the input distribution.
* @param deadband The deadband to use for the input distribution.
* @note The deadband must be non-negative.
* @note The deadband is applied around the center value of the input
* distribution.
*/
void set_deadband(T deadband) { deadband_ = deadband; }

/**
* @brief Map a value \p v from the input distribution into the configured
* output range (centered, default [-1,1]).
Expand Down
2 changes: 1 addition & 1 deletion docs/adc/adc_types.html
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@
<li><a href="index.html">ADC APIs</a> &raquo;</li>
<li>ADC Types</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/esp-cpp/espp/blob/626472a6/docs/en/adc/adc_types.rst" class="fa fa-github"> Edit on GitHub</a>
<a href="https://github.com/esp-cpp/espp/blob/ddf99a57/docs/en/adc/adc_types.rst" class="fa fa-github"> Edit on GitHub</a>
</li>
</ul>
<hr/>
Expand Down
4 changes: 2 additions & 2 deletions docs/adc/ads1x15.html
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@
<li><a href="index.html">ADC APIs</a> &raquo;</li>
<li>ADS1x15 I2C ADC</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/esp-cpp/espp/blob/626472a6/docs/en/adc/ads1x15.rst" class="fa fa-github"> Edit on GitHub</a>
<a href="https://github.com/esp-cpp/espp/blob/ddf99a57/docs/en/adc/ads1x15.rst" class="fa fa-github"> Edit on GitHub</a>
</li>
</ul>
<hr/>
Expand All @@ -168,7 +168,7 @@ <h2>API Reference<a class="headerlink" href="#api-reference" title="Permalink to
<section id="header-file">
<h3>Header File<a class="headerlink" href="#header-file" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/626472a6/components/ads1x15/include/ads1x15.hpp">components/ads1x15/include/ads1x15.hpp</a></p></li>
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/ddf99a57/components/ads1x15/include/ads1x15.hpp">components/ads1x15/include/ads1x15.hpp</a></p></li>
</ul>
</section>
<section id="classes">
Expand Down
4 changes: 2 additions & 2 deletions docs/adc/ads7138.html
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@
<li><a href="index.html">ADC APIs</a> &raquo;</li>
<li>ADS7138 I2C ADC</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/esp-cpp/espp/blob/626472a6/docs/en/adc/ads7138.rst" class="fa fa-github"> Edit on GitHub</a>
<a href="https://github.com/esp-cpp/espp/blob/ddf99a57/docs/en/adc/ads7138.rst" class="fa fa-github"> Edit on GitHub</a>
</li>
</ul>
<hr/>
Expand All @@ -173,7 +173,7 @@ <h2>API Reference<a class="headerlink" href="#api-reference" title="Permalink to
<section id="header-file">
<h3>Header File<a class="headerlink" href="#header-file" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/626472a6/components/ads7138/include/ads7138.hpp">components/ads7138/include/ads7138.hpp</a></p></li>
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/ddf99a57/components/ads7138/include/ads7138.hpp">components/ads7138/include/ads7138.hpp</a></p></li>
</ul>
</section>
<section id="classes">
Expand Down
4 changes: 2 additions & 2 deletions docs/adc/continuous_adc.html
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@
<li><a href="index.html">ADC APIs</a> &raquo;</li>
<li>Continuous ADC</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/esp-cpp/espp/blob/626472a6/docs/en/adc/continuous_adc.rst" class="fa fa-github"> Edit on GitHub</a>
<a href="https://github.com/esp-cpp/espp/blob/ddf99a57/docs/en/adc/continuous_adc.rst" class="fa fa-github"> Edit on GitHub</a>
</li>
</ul>
<hr/>
Expand All @@ -173,7 +173,7 @@ <h2>API Reference<a class="headerlink" href="#api-reference" title="Permalink to
<section id="header-file">
<h3>Header File<a class="headerlink" href="#header-file" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/626472a6/components/adc/include/continuous_adc.hpp">components/adc/include/continuous_adc.hpp</a></p></li>
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/ddf99a57/components/adc/include/continuous_adc.hpp">components/adc/include/continuous_adc.hpp</a></p></li>
</ul>
</section>
<section id="classes">
Expand Down
2 changes: 1 addition & 1 deletion docs/adc/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@
<li><a href="../index.html" class="icon icon-home"></a> &raquo;</li>
<li>ADC APIs</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/esp-cpp/espp/blob/626472a6/docs/en/adc/index.rst" class="fa fa-github"> Edit on GitHub</a>
<a href="https://github.com/esp-cpp/espp/blob/ddf99a57/docs/en/adc/index.rst" class="fa fa-github"> Edit on GitHub</a>
</li>
</ul>
<hr/>
Expand Down
4 changes: 2 additions & 2 deletions docs/adc/oneshot_adc.html
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@
<li><a href="index.html">ADC APIs</a> &raquo;</li>
<li>Oneshot ADC</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/esp-cpp/espp/blob/626472a6/docs/en/adc/oneshot_adc.rst" class="fa fa-github"> Edit on GitHub</a>
<a href="https://github.com/esp-cpp/espp/blob/ddf99a57/docs/en/adc/oneshot_adc.rst" class="fa fa-github"> Edit on GitHub</a>
</li>
</ul>
<hr/>
Expand All @@ -172,7 +172,7 @@ <h2>API Reference<a class="headerlink" href="#api-reference" title="Permalink to
<section id="header-file">
<h3>Header File<a class="headerlink" href="#header-file" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/626472a6/components/adc/include/oneshot_adc.hpp">components/adc/include/oneshot_adc.hpp</a></p></li>
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/ddf99a57/components/adc/include/oneshot_adc.hpp">components/adc/include/oneshot_adc.hpp</a></p></li>
</ul>
</section>
<section id="classes">
Expand Down
4 changes: 2 additions & 2 deletions docs/adc/tla2528.html
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@
<li><a href="index.html">ADC APIs</a> &raquo;</li>
<li>TLA2528 I2C ADC</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/esp-cpp/espp/blob/626472a6/docs/en/adc/tla2528.rst" class="fa fa-github"> Edit on GitHub</a>
<a href="https://github.com/esp-cpp/espp/blob/ddf99a57/docs/en/adc/tla2528.rst" class="fa fa-github"> Edit on GitHub</a>
</li>
</ul>
<hr/>
Expand All @@ -173,7 +173,7 @@ <h2>API Reference<a class="headerlink" href="#api-reference" title="Permalink to
<section id="header-file">
<h3>Header File<a class="headerlink" href="#header-file" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/626472a6/components/tla2528/include/tla2528.hpp">components/tla2528/include/tla2528.hpp</a></p></li>
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/ddf99a57/components/tla2528/include/tla2528.hpp">components/tla2528/include/tla2528.hpp</a></p></li>
</ul>
</section>
<section id="classes">
Expand Down
4 changes: 2 additions & 2 deletions docs/base_component.html
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@
<li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
<li>Base Compoenent</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/esp-cpp/espp/blob/626472a6/docs/en/base_component.rst" class="fa fa-github"> Edit on GitHub</a>
<a href="https://github.com/esp-cpp/espp/blob/ddf99a57/docs/en/base_component.rst" class="fa fa-github"> Edit on GitHub</a>
</li>
</ul>
<hr/>
Expand All @@ -162,7 +162,7 @@ <h2>API Reference<a class="headerlink" href="#api-reference" title="Permalink to
<section id="header-file">
<h3>Header File<a class="headerlink" href="#header-file" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/626472a6/components/base_component/include/base_component.hpp">components/base_component/include/base_component.hpp</a></p></li>
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/ddf99a57/components/base_component/include/base_component.hpp">components/base_component/include/base_component.hpp</a></p></li>
</ul>
</section>
<section id="classes">
Expand Down
4 changes: 2 additions & 2 deletions docs/base_peripheral.html
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@
<li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
<li>Base Peripheral</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/esp-cpp/espp/blob/626472a6/docs/en/base_peripheral.rst" class="fa fa-github"> Edit on GitHub</a>
<a href="https://github.com/esp-cpp/espp/blob/ddf99a57/docs/en/base_peripheral.rst" class="fa fa-github"> Edit on GitHub</a>
</li>
</ul>
<hr/>
Expand All @@ -166,7 +166,7 @@ <h2>API Reference<a class="headerlink" href="#api-reference" title="Permalink to
<section id="header-file">
<h3>Header File<a class="headerlink" href="#header-file" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/626472a6/components/base_peripheral/include/base_peripheral.hpp">components/base_peripheral/include/base_peripheral.hpp</a></p></li>
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/ddf99a57/components/base_peripheral/include/base_peripheral.hpp">components/base_peripheral/include/base_peripheral.hpp</a></p></li>
</ul>
</section>
<section id="classes">
Expand Down
2 changes: 1 addition & 1 deletion docs/battery/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
<li><a href="../index.html" class="icon icon-home"></a> &raquo;</li>
<li>Battery APIs</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/esp-cpp/espp/blob/626472a6/docs/en/battery/index.rst" class="fa fa-github"> Edit on GitHub</a>
<a href="https://github.com/esp-cpp/espp/blob/ddf99a57/docs/en/battery/index.rst" class="fa fa-github"> Edit on GitHub</a>
</li>
</ul>
<hr/>
Expand Down
4 changes: 2 additions & 2 deletions docs/battery/max1704x.html
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@
<li><a href="index.html">Battery APIs</a> &raquo;</li>
<li>MAX1704X</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/esp-cpp/espp/blob/626472a6/docs/en/battery/max1704x.rst" class="fa fa-github"> Edit on GitHub</a>
<a href="https://github.com/esp-cpp/espp/blob/ddf99a57/docs/en/battery/max1704x.rst" class="fa fa-github"> Edit on GitHub</a>
</li>
</ul>
<hr/>
Expand Down Expand Up @@ -180,7 +180,7 @@ <h2>API Reference<a class="headerlink" href="#api-reference" title="Permalink to
<section id="header-file">
<h3>Header File<a class="headerlink" href="#header-file" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/626472a6/components/max1704x/include/max1704x.hpp">components/max1704x/include/max1704x.hpp</a></p></li>
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/ddf99a57/components/max1704x/include/max1704x.hpp">components/max1704x/include/max1704x.hpp</a></p></li>
</ul>
</section>
<section id="classes">
Expand Down
Loading

0 comments on commit 73d80fa

Please sign in to comment.