mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-03-04 04:33:59 -04:00
APM: fixed handling of DO_REPEAT_SERVO and DO_REPEAT_RELAY
This commit is contained in:
parent
d7a53e67ed
commit
73340a5e5d
@ -565,24 +565,34 @@ int32_t wp_distance;
|
|||||||
// Distance between previous and next waypoint. Meters
|
// Distance between previous and next waypoint. Meters
|
||||||
static int32_t wp_totalDistance;
|
static int32_t wp_totalDistance;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
// event control state
|
||||||
// repeating event control
|
enum event_type {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
EVENT_TYPE_RELAY=0,
|
||||||
// Flag indicating current event type
|
EVENT_TYPE_SERVO=1
|
||||||
static byte event_id;
|
};
|
||||||
|
|
||||||
// when the event was started in ms
|
static struct {
|
||||||
static int32_t event_timer_ms;
|
enum event_type type;
|
||||||
|
|
||||||
// how long to delay the next firing of event in millis
|
// when the event was started in ms
|
||||||
static uint16_t event_delay_ms;
|
uint32_t start_time_ms;
|
||||||
|
|
||||||
|
// how long to delay the next firing of event in millis
|
||||||
|
uint16_t delay_ms;
|
||||||
|
|
||||||
|
// how many times to cycle : -1 (or -2) = forever, 2 = do one cycle, 4 = do two cycles
|
||||||
|
int16_t repeat;
|
||||||
|
|
||||||
|
// RC channel for servos
|
||||||
|
uint8_t rc_channel;
|
||||||
|
|
||||||
|
// PWM for servos
|
||||||
|
uint16_t servo_value;
|
||||||
|
|
||||||
|
// the value used to cycle events (alternate value to event_value)
|
||||||
|
uint16_t undo_value;
|
||||||
|
} event_state;
|
||||||
|
|
||||||
// how many times to cycle : -1 (or -2) = forever, 2 = do one cycle, 4 = do two cycles
|
|
||||||
static int16_t event_repeat = 0;
|
|
||||||
// per command value, such as PWM for servos
|
|
||||||
static int16_t event_value;
|
|
||||||
// the value used to cycle events (alternate value to event_value)
|
|
||||||
static int16_t event_undo_value;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Conditional command
|
// Conditional command
|
||||||
|
@ -1111,6 +1111,11 @@ void GCS_MAVLINK::handleMessage(mavlink_message_t* msg)
|
|||||||
result = MAV_RESULT_ACCEPTED;
|
result = MAV_RESULT_ACCEPTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MAV_CMD_DO_REPEAT_SERVO:
|
||||||
|
do_repeat_servo(packet.param1, packet.param2, packet.param3, packet.param4);
|
||||||
|
result = MAV_RESULT_ACCEPTED;
|
||||||
|
break;
|
||||||
|
|
||||||
case MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN:
|
case MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN:
|
||||||
if (packet.param1 == 1) {
|
if (packet.param1 == 1) {
|
||||||
#if CONFIG_APM_HARDWARE == APM_HARDWARE_APM2
|
#if CONFIG_APM_HARDWARE == APM_HARDWARE_APM2
|
||||||
|
@ -98,7 +98,8 @@ static void handle_process_do_command()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MAV_CMD_DO_REPEAT_SERVO:
|
case MAV_CMD_DO_REPEAT_SERVO:
|
||||||
do_repeat_servo();
|
do_repeat_servo(next_nonnav_command.p1, next_nonnav_command.alt,
|
||||||
|
next_nonnav_command.lat, next_nonnav_command.lng);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MAV_CMD_DO_REPEAT_RELAY:
|
case MAV_CMD_DO_REPEAT_RELAY:
|
||||||
@ -591,40 +592,32 @@ static void do_set_relay()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_repeat_servo()
|
static void do_repeat_servo(uint8_t channel, uint16_t servo_value,
|
||||||
|
int16_t repeat, uint8_t delay_time)
|
||||||
{
|
{
|
||||||
event_id = next_nonnav_command.p1 - 1;
|
extern RC_Channel *rc_ch[NUM_CHANNELS];
|
||||||
|
channel = channel - 1;
|
||||||
if(next_nonnav_command.p1 >= CH_5 + 1 && next_nonnav_command.p1 <= CH_8 + 1) {
|
if (channel < 5 || channel > 8) {
|
||||||
|
// not allowed
|
||||||
event_timer_ms = 0;
|
return;
|
||||||
event_delay_ms = next_nonnav_command.lng * 500.0; // /2 (half cycle time) * 1000 (convert to milliseconds)
|
|
||||||
event_repeat = next_nonnav_command.lat * 2;
|
|
||||||
event_value = next_nonnav_command.alt;
|
|
||||||
|
|
||||||
switch(next_nonnav_command.p1) {
|
|
||||||
case CH_5:
|
|
||||||
event_undo_value = g.rc_5.radio_trim;
|
|
||||||
break;
|
|
||||||
case CH_6:
|
|
||||||
event_undo_value = g.rc_6.radio_trim;
|
|
||||||
break;
|
|
||||||
case CH_7:
|
|
||||||
event_undo_value = g.rc_7.radio_trim;
|
|
||||||
break;
|
|
||||||
case CH_8:
|
|
||||||
event_undo_value = g.rc_8.radio_trim;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
event_state.rc_channel = channel;
|
||||||
|
event_state.type = EVENT_TYPE_SERVO;
|
||||||
|
|
||||||
|
event_state.start_time_ms = 0;
|
||||||
|
event_state.delay_ms = delay_time * 500UL;
|
||||||
|
event_state.repeat = repeat * 2;
|
||||||
|
event_state.servo_value = servo_value;
|
||||||
|
event_state.undo_value = rc_ch[channel]->radio_trim;
|
||||||
update_events();
|
update_events();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_repeat_relay()
|
static void do_repeat_relay()
|
||||||
{
|
{
|
||||||
event_id = RELAY_TOGGLE;
|
event_state.type = EVENT_TYPE_RELAY;
|
||||||
event_timer_ms = 0;
|
event_state.start_time_ms = 0;
|
||||||
event_delay_ms = next_nonnav_command.lat * 500.0; // /2 (half cycle time) * 1000 (convert to milliseconds)
|
// /2 (half cycle time) * 1000 (convert to milliseconds)
|
||||||
event_repeat = next_nonnav_command.alt * 2;
|
event_state.delay_ms = next_nonnav_command.lat * 500.0;
|
||||||
|
event_state.repeat = next_nonnav_command.alt * 2;
|
||||||
update_events();
|
update_events();
|
||||||
}
|
}
|
||||||
|
@ -86,28 +86,39 @@ void low_battery_event(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void update_events(void) // Used for MAV_CMD_DO_REPEAT_SERVO and MAV_CMD_DO_REPEAT_RELAY
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// repeating event control
|
||||||
|
|
||||||
|
/*
|
||||||
|
update state for MAV_CMD_DO_REPEAT_SERVO and MAV_CMD_DO_REPEAT_RELAY
|
||||||
|
*/
|
||||||
|
static void update_events(void)
|
||||||
{
|
{
|
||||||
if(event_repeat == 0 || (millis() - event_timer_ms) < event_delay_ms)
|
if (event_state.repeat == 0 || (millis() - event_state.start_time_ms) < event_state.delay_ms) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (event_repeat > 0) {
|
|
||||||
event_repeat--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(event_repeat != 0) { // event_repeat = -1 means repeat forever
|
// event_repeat = -1 means repeat forever
|
||||||
event_timer_ms = millis();
|
if (event_state.repeat != 0) {
|
||||||
|
event_state.start_time_ms = millis();
|
||||||
|
|
||||||
if (event_id >= CH_5 && event_id <= CH_8) {
|
switch (event_state.type) {
|
||||||
if(event_repeat%2) {
|
case EVENT_TYPE_SERVO:
|
||||||
APM_RC.OutputCh(event_id, event_value); // send to Servos
|
APM_RC.enable_out(event_state.rc_channel);
|
||||||
|
if (event_state.repeat & 1) {
|
||||||
|
APM_RC.OutputCh(event_state.rc_channel, event_state.undo_value);
|
||||||
} else {
|
} else {
|
||||||
APM_RC.OutputCh(event_id, event_undo_value);
|
APM_RC.OutputCh(event_state.rc_channel, event_state.servo_value);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EVENT_TYPE_RELAY:
|
||||||
|
relay.toggle();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event_id == RELAY_TOGGLE) {
|
if (event_state.repeat > 0) {
|
||||||
relay.toggle();
|
event_state.repeat--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user