2016-10-28 19:05:19 -03:00
|
|
|
#include <AP_Gripper/AP_Gripper_Servo.h>
|
2022-09-20 04:37:47 -03:00
|
|
|
|
|
|
|
#if AP_GRIPPER_SERVO_ENABLED
|
|
|
|
|
2018-08-09 14:08:55 -03:00
|
|
|
#include <GCS_MAVLink/GCS.h>
|
2019-10-25 03:13:14 -03:00
|
|
|
#include <AP_Logger/AP_Logger.h>
|
2023-01-24 17:39:44 -04:00
|
|
|
#include <SRV_Channel/SRV_Channel.h>
|
2019-10-25 03:13:14 -03:00
|
|
|
|
2018-08-09 14:08:55 -03:00
|
|
|
#if CONFIG_HAL_BOARD == HAL_BOARD_SITL
|
|
|
|
#include <SITL/SITL.h>
|
|
|
|
#endif
|
2016-10-28 19:05:19 -03:00
|
|
|
|
|
|
|
extern const AP_HAL::HAL& hal;
|
|
|
|
|
|
|
|
void AP_Gripper_Servo::init_gripper()
|
|
|
|
{
|
2022-07-31 22:45:52 -03:00
|
|
|
// move the servo to the neutral position
|
|
|
|
SRV_Channels::set_output_pwm(SRV_Channel::k_gripper, config.neutral_pwm);
|
2016-10-28 19:05:19 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
void AP_Gripper_Servo::grab()
|
|
|
|
{
|
2022-08-05 06:34:03 -03:00
|
|
|
// check if we are already grabbing
|
|
|
|
if (config.state == AP_Gripper::STATE_GRABBING) {
|
|
|
|
// do nothing
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// check if we are already grabbed
|
|
|
|
if (config.state == AP_Gripper::STATE_GRABBED) {
|
|
|
|
// inform user that we are already grabbed
|
2023-09-02 02:21:34 -03:00
|
|
|
GCS_SEND_TEXT(MAV_SEVERITY_INFO, "Gripper load grabbed");
|
2022-08-05 06:34:03 -03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-07-31 22:45:52 -03:00
|
|
|
// flag we are active and grabbing cargo
|
|
|
|
config.state = AP_Gripper::STATE_GRABBING;
|
|
|
|
|
2016-11-17 23:12:58 -04:00
|
|
|
// move the servo to the grab position
|
2017-01-06 21:06:40 -04:00
|
|
|
SRV_Channels::set_output_pwm(SRV_Channel::k_gripper, config.grab_pwm);
|
2022-08-06 10:35:17 -03:00
|
|
|
_last_grab_or_release = AP_HAL::millis();
|
2023-09-02 02:21:34 -03:00
|
|
|
GCS_SEND_TEXT(MAV_SEVERITY_INFO, "Gripper load grabbing");
|
2019-10-25 03:13:14 -03:00
|
|
|
AP::logger().Write_Event(LogEvent::GRIPPER_GRAB);
|
2016-10-28 19:05:19 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
void AP_Gripper_Servo::release()
|
|
|
|
{
|
2022-08-05 06:34:03 -03:00
|
|
|
// check if we are already releasing
|
|
|
|
if (config.state == AP_Gripper::STATE_RELEASING) {
|
|
|
|
// do nothing
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// check if we are already released
|
|
|
|
if (config.state == AP_Gripper::STATE_RELEASED) {
|
|
|
|
// inform user that we are already released
|
2023-09-02 02:21:34 -03:00
|
|
|
GCS_SEND_TEXT(MAV_SEVERITY_INFO, "Gripper load released");
|
2022-08-05 06:34:03 -03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-07-31 22:45:52 -03:00
|
|
|
// flag we are releasing cargo
|
|
|
|
config.state = AP_Gripper::STATE_RELEASING;
|
|
|
|
|
2016-10-28 19:05:19 -03:00
|
|
|
// move the servo to the release position
|
2017-01-06 21:06:40 -04:00
|
|
|
SRV_Channels::set_output_pwm(SRV_Channel::k_gripper, config.release_pwm);
|
2022-08-06 10:35:17 -03:00
|
|
|
_last_grab_or_release = AP_HAL::millis();
|
2023-09-02 02:21:34 -03:00
|
|
|
GCS_SEND_TEXT(MAV_SEVERITY_INFO, "Gripper load releasing");
|
2019-10-25 03:13:14 -03:00
|
|
|
AP::logger().Write_Event(LogEvent::GRIPPER_RELEASE);
|
2016-11-17 23:12:58 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool AP_Gripper_Servo::has_state_pwm(const uint16_t pwm) const
|
|
|
|
{
|
|
|
|
// return true if servo is in position represented by pwm
|
2017-01-06 21:06:40 -04:00
|
|
|
uint16_t current_pwm;
|
|
|
|
if (!SRV_Channels::get_output_pwm(SRV_Channel::k_gripper, current_pwm)) {
|
2016-11-17 23:12:58 -04:00
|
|
|
// function not assigned to a channel, perhaps?
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (current_pwm != pwm) {
|
|
|
|
// last action did not set pwm to the current value
|
2016-12-18 23:14:19 -04:00
|
|
|
// (e.g. last action was a grab not a release)
|
2016-11-17 23:12:58 -04:00
|
|
|
return false;
|
|
|
|
}
|
2022-08-06 10:35:17 -03:00
|
|
|
if (AP_HAL::millis() - _last_grab_or_release < SERVO_ACTUATION_TIME) {
|
2016-11-17 23:12:58 -04:00
|
|
|
// servo still moving....
|
|
|
|
return false;
|
|
|
|
}
|
2018-10-03 21:01:39 -03:00
|
|
|
return true;
|
2016-11-17 23:12:58 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool AP_Gripper_Servo::released() const
|
|
|
|
{
|
2022-07-31 22:45:52 -03:00
|
|
|
return (config.state == AP_Gripper::STATE_RELEASED);
|
2016-11-17 23:12:58 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool AP_Gripper_Servo::grabbed() const
|
|
|
|
{
|
2022-07-31 22:45:52 -03:00
|
|
|
return (config.state == AP_Gripper::STATE_GRABBED);
|
2016-10-28 19:05:19 -03:00
|
|
|
}
|
|
|
|
|
2016-11-17 23:12:58 -04:00
|
|
|
// type-specific periodic updates:
|
2022-08-06 10:35:17 -03:00
|
|
|
void AP_Gripper_Servo::update_gripper()
|
|
|
|
{
|
2022-07-31 22:45:52 -03:00
|
|
|
// Check for successful grabbed or released
|
|
|
|
if (config.state == AP_Gripper::STATE_GRABBING && has_state_pwm(config.grab_pwm)) {
|
|
|
|
config.state = AP_Gripper::STATE_GRABBED;
|
|
|
|
} else if (config.state == AP_Gripper::STATE_RELEASING && has_state_pwm(config.release_pwm)) {
|
|
|
|
config.state = AP_Gripper::STATE_RELEASED;
|
|
|
|
}
|
2022-08-06 10:35:17 -03:00
|
|
|
}
|
2016-12-19 23:18:18 -04:00
|
|
|
|
|
|
|
bool AP_Gripper_Servo::valid() const
|
|
|
|
{
|
|
|
|
if (!AP_Gripper_Backend::valid()) {
|
|
|
|
return false;
|
|
|
|
}
|
2017-01-06 21:06:40 -04:00
|
|
|
if (!SRV_Channels::function_assigned(SRV_Channel::k_gripper)) {
|
2016-12-19 23:18:18 -04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2022-09-20 04:37:47 -03:00
|
|
|
|
|
|
|
#endif // AP_GRIPPER_SERVO_ENABLED
|