/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
/*
The Daiwa winch is produced by a Japanese company called Okaya.
There are two PWM controls supported:
- the rate control for releasing (high PWM) or retracting (low PWM) the line
- the clutch control has three settings:
- released (high PWM) lets the winch spin freely
- engaged soft (middle PWM) allows the rate control to work but it may slip
if too much tension is required. This driver does not use this setting.
- engaged hard (low PWM) allows the rate control to work regardless of tension.
A telemetry output from the winch is connected to the autopilot and provides
the amount of line released, tension, clutch setting, etc.
*/
#pragma once
#include
#if AP_WINCH_DAIWA_ENABLED
class AP_Winch_Daiwa : public AP_Winch_Backend {
public:
using AP_Winch_Backend::AP_Winch_Backend;
// true if winch is healthy
bool healthy() const override;
// initialise the winch
void init() override;
// read telemetry from the winch and output controls
void update() override;
// returns current length of line deployed
float get_current_length() const override { return latest.line_length; }
// send status to ground station
void send_status(const GCS_MAVLINK &channel) override;
// write log
void write_log() override;
private:
// read incoming data from winch and update intermediate and latest structures
void read_data_from_winch();
// update pwm outputs to control winch
void control_winch();
// returns the rate which may be modified to unstick the winch
// if the winch stops, the rate is temporarily set to zero
// now_ms should be set to the current system time
// rate should be the rate used to calculate the final PWM output to the winch
float get_stuck_protected_rate(uint32_t now_ms, float rate);
static const uint8_t buff_len_max = 20; // buffer maximum length
static const int16_t output_dz = 100; // output deadzone in scale of -1000 to +1000
const float line_length_correction_factor = 0.003333f; // convert winch counter to meters
AP_HAL::UARTDriver *uart;
char buff[buff_len_max]; // buffer holding latest data from winch
uint8_t buff_len; // number of bytes in buff
// winch data
// latest holds most recent complete data received
// intermediate holds partial results currently being processed
struct WinchData {
uint32_t time_ms; // winch system time in milliseconds
float line_length; // length of line released in meters
uint16_t tension_uncorrected; // uncorrected tension in grams (0 to 1024)
uint16_t tension_corrected; // corrected tension in grams (0 to 1024)
bool thread_end; // true if end of thread has been detected
uint8_t moving; // 0:stopped, 1:retracting line, 2:extending line, 3:clutch engaged, 4:zero reset
uint8_t clutch; // 0:clutch off, 1:clutch engaged weakly, 2:clutch engaged strongly, motor can spin freely
uint8_t speed_pct; // speed motor is moving as a percentage
float voltage; // battery voltage (in voltes)
float current; // current draw (in amps)
float pcb_temp; // PCB temp in C
float motor_temp; // motor temp in C
} latest, intermediate;
uint32_t data_update_ms; // system time that latest was last updated
uint32_t control_update_ms; // last time control_winch was called
// parsing state
enum class ParseState : uint8_t {
WAITING_FOR_TIME = 0,
WAITING_FOR_SPOOL,
WAITING_FOR_TENSION1,
WAITING_FOR_TENSION2,
WAITING_FOR_THREAD_END,
WAITING_FOR_MOVING,
WAITING_FOR_CLUTCH,
WAITING_FOR_SPEED,
WAITING_FOR_VOLTAGE,
WAITING_FOR_CURRENT,
WAITING_FOR_PCB_TEMP,
WAITING_FOR_MOTOR_TEMP
} parse_state;
// update user with changes to winch state via send text messages
static const char* send_text_prefix;// send text prefix string to reduce flash cost
void update_user();
struct {
uint32_t last_ms; // system time of last update to user
bool healthy; // latest reported health
float line_length;
bool thread_end; // true if end of thread has been detected
uint8_t moving; // 0:stopped, 1:retracting line, 2:extending line, 3:clutch engaged, 4:zero reset
uint8_t clutch; // 0:clutch off, 1:clutch engaged weakly, 2:clutch engaged strongly, motor can spin freely
} user_update;
// stuck protection
struct {
uint32_t last_update_ms; // system time that stuck protection was last called
uint32_t stuck_start_ms; // system time that winch became stuck (0 if not stuck)
bool user_notified; // true if user has been notified that winch is stuck
} stuck_protection;
};
#endif // AP_WINCH_DAIWA_ENABLED