|
|
|
@ -2,9 +2,6 @@
@@ -2,9 +2,6 @@
|
|
|
|
|
#include "Copter.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Copter::do_avoid_action(){ |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
// bool Copter::close_to_EKF_origin(const Location& loc)
|
|
|
|
|
// {
|
|
|
|
|
// // check distance to EKF origin
|
|
|
|
@ -137,7 +134,205 @@ void Copter::zr_SuperSlowLoop(){
@@ -137,7 +134,205 @@ void Copter::zr_SuperSlowLoop(){
|
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Copter::do_avoid_action(){ |
|
|
|
|
float proxy_dist = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if CONFIG_HAL_BOARD == HAL_BOARD_SITL |
|
|
|
|
uint16_t rc10_in = RC_Channels::rc_channel(CH_6)->get_radio_in(); |
|
|
|
|
proxy_dist = (rc10_in - 1100)/900.0*50.0; |
|
|
|
|
#else |
|
|
|
|
if(avoid.get_zr_mode() == 1){ |
|
|
|
|
|
|
|
|
|
AP_Proximity *proximity = AP::proximity(); |
|
|
|
|
if(proximity == nullptr) |
|
|
|
|
return; |
|
|
|
|
proximity->get_horizontal_distance(0,proxy_dist); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
if(avoid.get_zr_mode() == 2){ |
|
|
|
|
uint16_t rc10_in = RC_Channels::rc_channel(CH_12)->get_radio_in(); |
|
|
|
|
proxy_dist = (rc10_in - 1100)/900.0*50.0; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
avoid_area_detect(proxy_dist); |
|
|
|
|
avoid_state(proxy_dist); |
|
|
|
|
avoid_action(proxy_area,proxy_state,proxy_dist); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t Copter::avoid_area_detect(float dist) |
|
|
|
|
{ |
|
|
|
|
Proxy_Area area; |
|
|
|
|
if(dist < avoid.get_zr_avd_min()){ |
|
|
|
|
|
|
|
|
|
if(area != PROXY_TOO_CLOSE) // 前一个状态不是障碍物过近
|
|
|
|
|
area = PROXY_OUTRANGE; |
|
|
|
|
area = PROXY_OUTRANGE; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
else if(dist< avoid.get_zr_avd_trig()) |
|
|
|
|
area = PROXY_TOO_CLOSE; |
|
|
|
|
else if(dist<avoid.get_zr_avd_max()) |
|
|
|
|
area = PROXY_FIND_BARRIER; |
|
|
|
|
else { |
|
|
|
|
|
|
|
|
|
area = PROXY_OUTRANGE; |
|
|
|
|
} |
|
|
|
|
proxy_area = area; |
|
|
|
|
return area; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint8_t Copter::avoid_state(float dist) |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
Proxy_State state; |
|
|
|
|
static float previous_dist = 0; |
|
|
|
|
float delt_dist = dist - previous_dist; |
|
|
|
|
previous_dist = dist; |
|
|
|
|
if(delt_dist > 1) |
|
|
|
|
state = PROXY_LEAVE; |
|
|
|
|
else if(delt_dist < -1) |
|
|
|
|
state = PROXY_APPROACH; |
|
|
|
|
else |
|
|
|
|
state = PROXY_HOLD; |
|
|
|
|
proxy_state = state; |
|
|
|
|
return state; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Copter::avoid_action(uint8_t area,uint8_t state,float dist) |
|
|
|
|
{ |
|
|
|
|
static uint8_t delay_cnt; |
|
|
|
|
static Proxy_Action action; |
|
|
|
|
static const float get_org_max_speed = wp_nav->get_default_speed_xy(); |
|
|
|
|
static float avoid_slow_speed = 100.0f; |
|
|
|
|
|
|
|
|
|
Vector3f pos_neu_cm; |
|
|
|
|
static int32_t max_climb_alt = 0; |
|
|
|
|
|
|
|
|
|
int32_t turn_yaw; |
|
|
|
|
|
|
|
|
|
switch (action) |
|
|
|
|
{ |
|
|
|
|
case PROXY_WAIT: |
|
|
|
|
if(area == PROXY_FIND_BARRIER && state == PROXY_APPROACH) |
|
|
|
|
action = PROXY_SLOW_DOWN; |
|
|
|
|
if(area == PROXY_TOO_CLOSE) |
|
|
|
|
action = PROXY_BRAKE; |
|
|
|
|
break; |
|
|
|
|
case PROXY_SLOW_DOWN: |
|
|
|
|
if(state == PROXY_APPROACH){ |
|
|
|
|
|
|
|
|
|
avoid_slow_speed = (dist - avoid.get_zr_avd_trig())/(avoid.get_zr_avd_max() - avoid.get_zr_avd_trig())*loiter_nav->get_loiter_speed(); |
|
|
|
|
avoid_slow_speed = MAX(avoid_slow_speed,0); |
|
|
|
|
|
|
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"NOTICE: 发现障碍物,距离:%3.2fm,v:%.2f",dist,avoid_slow_speed); |
|
|
|
|
wp_nav->set_speed_xy(avoid_slow_speed); |
|
|
|
|
loiter_nav->set_loiter_speed(avoid_slow_speed); |
|
|
|
|
// last_prx_diff = dist;
|
|
|
|
|
} |
|
|
|
|
if(area == PROXY_TOO_CLOSE) |
|
|
|
|
action = PROXY_BRAKE; |
|
|
|
|
break; |
|
|
|
|
case PROXY_BRAKE: |
|
|
|
|
if(state != PROXY_LEAVE){ |
|
|
|
|
gcs().send_text(MAV_SEVERITY_CRITICAL,"障碍物距离过近:%3.2fm,刹车",dist); |
|
|
|
|
set_mode(Mode::Number::BRAKE,ModeReason::AVOIDANCE); |
|
|
|
|
action = PROXY_DELAY; |
|
|
|
|
delay_cnt = 0; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case PROXY_DELAY: |
|
|
|
|
if(delay_cnt > 30){ |
|
|
|
|
|
|
|
|
|
set_mode(Mode::Number::GUIDED,ModeReason::AVOIDANCE); |
|
|
|
|
// turn_yaw = current_loc.get_bearing_to(ahrs.get_home());
|
|
|
|
|
// bool need_turn_yaw = abs(ahrs.yaw_sensor - turn_yaw)<4500;
|
|
|
|
|
// if(need_turn_yaw){
|
|
|
|
|
// action = PROXY_CLIMB;
|
|
|
|
|
max_climb_alt = current_loc.alt+avoid.get_zr_avd_max_climb(); |
|
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"NOTICE:准备爬升,Now:%d,MAX:%d,",current_loc.alt,max_climb_alt); |
|
|
|
|
|
|
|
|
|
// }else{
|
|
|
|
|
// action = PROXY_RTL;
|
|
|
|
|
// max_climb_alt = current_loc.alt;
|
|
|
|
|
// gcs().send_text(MAV_SEVERITY_INFO,"NOTICE:角度在安全范围:%d,直接返航",abs(ahrs.yaw_sensor - turn_yaw));
|
|
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
action = PROXY_CLIMB; |
|
|
|
|
delay_cnt = 0; |
|
|
|
|
} |
|
|
|
|
if(control_mode == Mode::Number::LOITER || control_mode == Mode::Number::ALT_HOLD ){ |
|
|
|
|
action = PROXY_WAIT; |
|
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"NOTICE:切换到人为控制"); |
|
|
|
|
} |
|
|
|
|
delay_cnt+=1; |
|
|
|
|
break; |
|
|
|
|
case PROXY_CLIMB: |
|
|
|
|
if (!current_loc.get_vector_from_origin_NEU(pos_neu_cm)) { |
|
|
|
|
|
|
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"NOTICE:无法获取位置"); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
pos_neu_cm.z += 1000; |
|
|
|
|
turn_yaw = current_loc.get_bearing_to(ahrs.get_home()); |
|
|
|
|
mode_guided.set_destination(pos_neu_cm, true, turn_yaw, true, 200, false); |
|
|
|
|
|
|
|
|
|
// mode_guided.set_destination(pos_neu_cm, false, 0, false, 0, false);
|
|
|
|
|
if(current_loc.alt > max_climb_alt){ |
|
|
|
|
action = PROXY_NEED_CTL; |
|
|
|
|
gcs().send_text(MAV_SEVERITY_CRITICAL,"超出爬升高度限制:%d,请手动控制",current_loc.alt); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
if(area == PROXY_OUTRANGE){ |
|
|
|
|
action = PROXY_RTL; |
|
|
|
|
max_climb_alt = current_loc.alt + 1000; |
|
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"NOTICE:已避开障碍,准备返航"); |
|
|
|
|
} |
|
|
|
|
if(control_mode == Mode::Number::LOITER || control_mode == Mode::Number::ALT_HOLD ){ |
|
|
|
|
action = PROXY_WAIT; |
|
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"NOTICE:切换到人为控制"); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case PROXY_RTL: |
|
|
|
|
if(current_loc.alt < max_climb_alt) |
|
|
|
|
{ |
|
|
|
|
if (!current_loc.get_vector_from_origin_NEU(pos_neu_cm)) { |
|
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"NOTICE:无法获取位置"); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
pos_neu_cm.z += max_climb_alt - current_loc.alt + 500; |
|
|
|
|
// turn_yaw = current_loc.get_bearing_to(ahrs.get_home());
|
|
|
|
|
mode_guided.set_destination(pos_neu_cm, false, 0, false, 0, false); |
|
|
|
|
if(control_mode != Mode::Number::GUIDED){ |
|
|
|
|
action = PROXY_WAIT; |
|
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"NOTICE:切换到人为控制"); |
|
|
|
|
} |
|
|
|
|
}else{
|
|
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"NOTICE:开始返航"); |
|
|
|
|
set_mode(Mode::Number::RTL,ModeReason::AVOIDANCE); |
|
|
|
|
wp_nav->set_speed_xy(get_org_max_speed); |
|
|
|
|
loiter_nav->set_loiter_speed(get_org_max_speed); |
|
|
|
|
action = PROXY_WAIT; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
case PROXY_NEED_CTL: |
|
|
|
|
|
|
|
|
|
if(area == PROXY_OUTRANGE){ |
|
|
|
|
action = PROXY_WAIT; |
|
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"NOTICE:人为控制,已离开障碍"); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif |