mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-22 20:36:06 +08:00
potential fields for collision avoidance
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE module SYSTEM "module.dtd">
|
||||
|
||||
<module name="multi">
|
||||
<header>
|
||||
<file name="potential.h"/>
|
||||
</header>
|
||||
<init fun="potential_init()"/>
|
||||
<makefile>
|
||||
<file name="potential.c"/>
|
||||
</makefile>
|
||||
</module>
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
/** \file potential.c
|
||||
*/
|
||||
|
||||
#define POTENTIAL_C
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#ifndef DOWNLINK_DEVICE
|
||||
#define DOWNLINK_DEVICE DOWNLINK_AP_DEVICE
|
||||
#endif
|
||||
#include "downlink.h"
|
||||
#include "dl_protocol.h"
|
||||
|
||||
#include "potential.h"
|
||||
#include "estimator.h"
|
||||
#include "fw_h_ctl.h"
|
||||
#include "fw_v_ctl.h"
|
||||
#include "autopilot.h"
|
||||
#include "gps.h"
|
||||
#include "airframe.h"
|
||||
|
||||
//#include <stdio.h>
|
||||
|
||||
struct force_ potential_force;
|
||||
|
||||
float force_pos_gain;
|
||||
float force_speed_gain;
|
||||
float force_climb_gain;
|
||||
|
||||
#ifndef FORCE_POS_GAIN
|
||||
#define FORCE_POS_GAIN 1.
|
||||
#endif
|
||||
|
||||
#ifndef FORCE_SPEED_GAIN
|
||||
#define FORCE_SPEED_GAIN 1.
|
||||
#endif
|
||||
|
||||
#ifndef FORCE_CLIMB_GAIN
|
||||
#define FORCE_CLIMB_GAIN 1.
|
||||
#endif
|
||||
|
||||
#ifndef FORCE_MAX_DIST
|
||||
#define FORCE_MAX_DIST 100.
|
||||
#endif
|
||||
|
||||
void potential_init(void) {
|
||||
|
||||
potential_force.east = 0.;
|
||||
potential_force.north = 0.;
|
||||
potential_force.alt = 0.;
|
||||
|
||||
force_pos_gain = FORCE_POS_GAIN;
|
||||
force_speed_gain = FORCE_SPEED_GAIN;
|
||||
force_climb_gain = FORCE_CLIMB_GAIN;
|
||||
|
||||
}
|
||||
|
||||
int potential_task(void) {
|
||||
|
||||
uint8_t i;
|
||||
|
||||
float ch = cosf(estimator_hspeed_dir);
|
||||
float sh = sinf(estimator_hspeed_dir);
|
||||
potential_force.east = 0.;
|
||||
potential_force.north = 0.;
|
||||
potential_force.alt = 0.;
|
||||
|
||||
// compute control forces
|
||||
int8_t nb = 0;
|
||||
for (i = 0; i < NB_ACS; ++i) {
|
||||
if (the_acs[i].ac_id == AC_ID) continue;
|
||||
struct ac_info_ * ac = get_ac_info(the_acs[i].ac_id);
|
||||
float delta_t = Max((int)(gps_itow - ac->itow) / 1000., 0.);
|
||||
// if AC not responding for too long, continue, else compute force
|
||||
if (delta_t > CARROT) continue;
|
||||
else {
|
||||
float sha = sinf(ac->course);
|
||||
float cha = cosf(ac->course);
|
||||
float de = ac->east + sha*delta_t - estimator_x;
|
||||
if (de > FORCE_MAX_DIST || de < -FORCE_MAX_DIST) continue;
|
||||
float dn = ac->north + cha*delta_t - estimator_y;
|
||||
if (dn > FORCE_MAX_DIST || dn < -FORCE_MAX_DIST) continue;
|
||||
float da = ac->alt + ac->climb*delta_t - estimator_z;
|
||||
if (da > FORCE_MAX_DIST || da < -FORCE_MAX_DIST) continue;
|
||||
float dist = sqrtf(de*de + dn*dn + da*da);
|
||||
if (dist == 0.) continue;
|
||||
float dve = estimator_hspeed_mod * sh - ac->gspeed * sha;
|
||||
float dvn = estimator_hspeed_mod * ch - ac->gspeed * cha;
|
||||
float dva = estimator_z_dot - the_acs[i].climb;
|
||||
float scal = dve*de + dvn*dn + dva*da;
|
||||
if (scal < 0.) continue; // No risk of collision
|
||||
float d3 = dist * dist * dist;
|
||||
potential_force.east += scal * de / d3;
|
||||
potential_force.north += scal * dn / d3;
|
||||
potential_force.alt += scal * da / d3;
|
||||
++nb;
|
||||
}
|
||||
}
|
||||
if (nb == 0) return TRUE;
|
||||
//potential_force.east /= nb;
|
||||
//potential_force.north /= nb;
|
||||
//potential_force.alt /= nb;
|
||||
|
||||
// set commands
|
||||
NavVerticalAutoThrottleMode(0.);
|
||||
|
||||
// carrot
|
||||
float dx = -force_pos_gain * potential_force.east;
|
||||
float dy = -force_pos_gain * potential_force.north;
|
||||
desired_x += dx;
|
||||
desired_y += dy;
|
||||
// fly to desired
|
||||
fly_to_xy(desired_x, desired_y);
|
||||
|
||||
// speed loop
|
||||
float cruise = V_CTL_AUTO_THROTTLE_NOMINAL_CRUISE_THROTTLE;
|
||||
cruise += -force_speed_gain * (potential_force.north * ch + potential_force.east * sh);
|
||||
Bound(cruise, V_CTL_AUTO_THROTTLE_MIN_CRUISE_THROTTLE, V_CTL_AUTO_THROTTLE_MAX_CRUISE_THROTTLE);
|
||||
potential_force.speed = cruise;
|
||||
v_ctl_auto_throttle_cruise_throttle = cruise;
|
||||
|
||||
// climb loop
|
||||
potential_force.climb = -force_climb_gain * potential_force.alt;
|
||||
BoundAbs(potential_force.climb, V_CTL_ALTITUDE_MAX_CLIMB);
|
||||
NavVerticalClimbMode(potential_force.climb);
|
||||
|
||||
DOWNLINK_SEND_POTENTIAL(DefaultChannel,&potential_force.east,&potential_force.north,&potential_force.alt,&potential_force.speed,&potential_force.climb);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/** \file potential.h
|
||||
* \brief flying with potential field to avoid collision
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef POTENTIAL_H
|
||||
#define POTENTIAL_H
|
||||
|
||||
#include "nav.h"
|
||||
#include "traffic_info.h"
|
||||
|
||||
struct force_ {
|
||||
float east;
|
||||
float north;
|
||||
float alt;
|
||||
float speed;
|
||||
float climb;
|
||||
};
|
||||
|
||||
extern struct force_ potential_force;
|
||||
|
||||
extern float force_pos_gain;
|
||||
extern float force_speed_gain;
|
||||
extern float force_climb_gain;
|
||||
|
||||
extern void potential_init(void);
|
||||
|
||||
extern int potential_task(void);
|
||||
|
||||
#endif /* POTENTIAL_H */
|
||||
Reference in New Issue
Block a user