Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/libraries/AC_Sprayer/AC_Sprayer.cpp
Views: 1798
#include "AC_Sprayer_config.h"12#if HAL_SPRAYER_ENABLED34#include "AC_Sprayer.h"5#include <AP_AHRS/AP_AHRS.h>6#include <AP_HAL/AP_HAL.h>7#include <AP_Math/AP_Math.h>8#include <SRV_Channel/SRV_Channel.h>910extern const AP_HAL::HAL& hal;1112// ------------------------------1314const AP_Param::GroupInfo AC_Sprayer::var_info[] = {15// @Param: ENABLE16// @DisplayName: Sprayer enable/disable17// @Description: Allows you to enable (1) or disable (0) the sprayer18// @Values: 0:Disabled,1:Enabled19// @User: Standard20AP_GROUPINFO_FLAGS("ENABLE", 0, AC_Sprayer, _enabled, 0, AP_PARAM_FLAG_ENABLE),2122// @Param: PUMP_RATE23// @DisplayName: Pump speed24// @Description: Desired pump speed when travelling 1m/s expressed as a percentage25// @Units: %26// @Range: 0 10027// @User: Standard28AP_GROUPINFO("PUMP_RATE", 1, AC_Sprayer, _pump_pct_1ms, AC_SPRAYER_DEFAULT_PUMP_RATE),2930// @Param: SPINNER31// @DisplayName: Spinner rotation speed32// @Description: Spinner's rotation speed in PWM (a higher rate will disperse the spray over a wider area horizontally)33// @Units: ms34// @Range: 1000 200035// @User: Standard36AP_GROUPINFO("SPINNER", 2, AC_Sprayer, _spinner_pwm, AC_SPRAYER_DEFAULT_SPINNER_PWM),3738// @Param: SPEED_MIN39// @DisplayName: Speed minimum40// @Description: Speed minimum at which we will begin spraying41// @Units: cm/s42// @Range: 0 100043// @User: Standard44AP_GROUPINFO("SPEED_MIN", 3, AC_Sprayer, _speed_min, AC_SPRAYER_DEFAULT_SPEED_MIN),4546// @Param: PUMP_MIN47// @DisplayName: Pump speed minimum48// @Description: Minimum pump speed expressed as a percentage49// @Units: %50// @Range: 0 10051// @User: Standard52AP_GROUPINFO("PUMP_MIN", 4, AC_Sprayer, _pump_min_pct, AC_SPRAYER_DEFAULT_PUMP_MIN),5354AP_GROUPEND55};5657AC_Sprayer::AC_Sprayer()58{59if (_singleton) {60#if CONFIG_HAL_BOARD == HAL_BOARD_SITL61AP_HAL::panic("Too many sprayers");62#endif63return;64}65_singleton = this;6667AP_Param::setup_object_defaults(this, var_info);6869// check for silly parameter values70if (_pump_pct_1ms < 0.0f || _pump_pct_1ms > 100.0f) {71_pump_pct_1ms.set_and_save(AC_SPRAYER_DEFAULT_PUMP_RATE);72}73if (_spinner_pwm < 0) {74_spinner_pwm.set_and_save(AC_SPRAYER_DEFAULT_SPINNER_PWM);75}7677// To-Do: ensure that the pump and spinner servo channels are enabled78}7980/*81* Get the AP_Sprayer singleton82*/83AC_Sprayer *AC_Sprayer::_singleton;84AC_Sprayer *AC_Sprayer::get_singleton()85{86return _singleton;87}8889void AC_Sprayer::run(const bool activate)90{91// return immediately if no change92if (_flags.running == activate) {93return;94}9596// set flag indicate whether spraying is permitted:97// do not allow running to be set to true if we are currently not enabled98_flags.running = _enabled && activate;99100// turn off the pump and spinner servos if necessary101if (!_flags.running) {102stop_spraying();103}104}105106void AC_Sprayer::stop_spraying()107{108SRV_Channels::set_output_limit(SRV_Channel::k_sprayer_pump, SRV_Channel::Limit::MIN);109SRV_Channels::set_output_limit(SRV_Channel::k_sprayer_spinner, SRV_Channel::Limit::MIN);110111_flags.spraying = false;112}113114/// update - adjust pwm of servo controlling pump speed according to the desired quantity and our horizontal speed115void AC_Sprayer::update()116{117// exit immediately if we are disabled or shouldn't be running118if (!_enabled || !running()) {119run(false);120return;121}122123// exit immediately if the pump function has not been set-up for any servo124if (!SRV_Channels::function_assigned(SRV_Channel::k_sprayer_pump)) {125return;126}127128// get horizontal velocity129Vector3f velocity;130if (!AP::ahrs().get_velocity_NED(velocity)) {131// treat unknown velocity as zero which should lead to pump stopping132// velocity will already be zero but this avoids a coverity warning133velocity.zero();134}135136float ground_speed = velocity.xy().length() * 100.0;137138// get the current time139const uint32_t now = AP_HAL::millis();140141bool should_be_spraying = _flags.spraying;142// check our speed vs the minimum143if (ground_speed >= _speed_min) {144// if we are not already spraying145if (!_flags.spraying) {146// set the timer if this is the first time we've surpassed the min speed147if (_speed_over_min_time == 0) {148_speed_over_min_time = now;149}else{150// check if we've been over the speed long enough to engage the sprayer151if((now - _speed_over_min_time) > AC_SPRAYER_DEFAULT_TURN_ON_DELAY) {152should_be_spraying = true;153_speed_over_min_time = 0;154}155}156}157// reset the speed under timer158_speed_under_min_time = 0;159} else {160// we are under the min speed.161if (_flags.spraying) {162// set the timer if this is the first time we've dropped below the min speed163if (_speed_under_min_time == 0) {164_speed_under_min_time = now;165}else{166// check if we've been over the speed long enough to engage the sprayer167if((now - _speed_under_min_time) > AC_SPRAYER_DEFAULT_SHUT_OFF_DELAY) {168should_be_spraying = false;169_speed_under_min_time = 0;170}171}172}173// reset the speed over timer174_speed_over_min_time = 0;175}176177// if testing pump output speed as if travelling at 1m/s178if (_flags.testing) {179ground_speed = 100.0f;180should_be_spraying = true;181}182183// if spraying or testing update the pump servo position184if (should_be_spraying) {185float pos = ground_speed * _pump_pct_1ms;186pos = MAX(pos, 100 *_pump_min_pct); // ensure min pump speed187pos = MIN(pos,10000); // clamp to range188SRV_Channels::move_servo(SRV_Channel::k_sprayer_pump, pos, 0, 10000);189SRV_Channels::set_output_pwm(SRV_Channel::k_sprayer_spinner, _spinner_pwm);190_flags.spraying = true;191} else {192stop_spraying();193}194}195196namespace AP {197198AC_Sprayer *sprayer()199{200return AC_Sprayer::get_singleton();201}202203};204#endif // HAL_SPRAYER_ENABLED205206207