00001 #include "safety.h"
00002 #include "Controller.h"
00003 #include "obstacle.h"
00004 #include <art/steering.h>
00005 #include <art/Safety.h>
00006
00007 Safety::Safety(Navigator *navptr, int _verbose, int mode):
00008 Controller(navptr, _verbose)
00009 {
00010 _mode=mode;
00011 safety = new Safety_Distance(_verbose);
00012 }
00013
00014 Safety::~Safety()
00015 {
00016 delete safety;
00017 }
00018
00019 void Safety::configure(ConfigFile* cf, int section)
00020 {
00021
00022 if (_mode==0)
00023 {
00024 far_slow_ratio = cf->ReadFloat(section, "far_slow_ratio", 0.75);
00025 near_slow_ratio = cf->ReadFloat(section, "near_slow_ratio", 0.5);
00026
00027 far_safety_time = cf->ReadFloat(section, "far_safety_time", 3);
00028 near_safety_time = cf->ReadFloat(section, "near_safety_time", 2);
00029 collision_safety_time = cf->ReadFloat(section, "collision_safety_time", 1);
00030 }
00031 else if (_mode==1)
00032 {
00033 far_slow_ratio = cf->ReadFloat(section, "zone_far_slow_ratio", 0.75);
00034 near_slow_ratio = cf->ReadFloat(section, "zone_near_slow_ratio", 0.5);
00035
00036 far_safety_time = cf->ReadFloat(section, "zone_far_safety_time", 3);
00037 near_safety_time = cf->ReadFloat(section, "zone_near_safety_time", 2);
00038 collision_safety_time = cf->ReadFloat(section, "zone_collision_safety_time", 1.0);
00039 }
00040 else{
00041 far_slow_ratio = cf->ReadFloat(section, "parking_far_slow_ratio", 0.75);
00042 near_slow_ratio = cf->ReadFloat(section, "parking_near_slow_ratio", 0.5);
00043
00044 far_safety_time = cf->ReadFloat(section, "parking_far_safety_time", 1.5);
00045 near_safety_time = cf->ReadFloat(section, "parking_near_safety_time", 1);
00046 collision_safety_time = cf->ReadFloat(section, "parking_collision_safety_time", 1.0);
00047 }
00048
00049 safety_speed = cf->ReadFloat(section, "safety_speed", 2.0);
00050
00051 ART_MSG(2, "Safety is in mode %d",_mode);
00052 ART_MSG(2, "\tMinimum nonzero safety speed is %.3f m/s", safety_speed);
00053
00054 ART_MSG(2, "\tMultiply speed by %.2f if collision in %f seconds",
00055 far_slow_ratio, far_safety_time);
00056 ART_MSG(2, "\tMultiply speed by %.2f if collision in %f seconds",
00057 near_slow_ratio, near_safety_time);
00058 ART_MSG(2, "\tBrake immediately if collision in %f seconds",
00059 near_safety_time);
00060 }
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 Controller::result_t Safety::control(pilot_command_t &retpcmd)
00077 {
00078 pilot_command_t pcmd=retpcmd;
00079 if (navdata->reverse)
00080 pcmd.velocity*=-1;
00081
00082
00083
00084 player_pose2d_t tmp=estimate->pos;
00085 float min_val=Infinite::distance;
00086
00087
00088
00089 float ret_val=
00090 safety->minimum_obstacle_to_arc(tmp,
00091 estimate->vel.px*collision_safety_time,
00092 estimate->vel.pa*collision_safety_time,
00093 obstacle->lasers->all_obstacle_list,
00094 tmp);
00095 if (Epsilon::equal(ret_val,0.0))
00096 {
00097 return halt_immediately(retpcmd);
00098 }
00099
00100
00101
00102 bool collision_obst=false;
00103 bool collision;
00104 result_t result = OK;
00105
00106 do {
00107 tmp=estimate->pos;
00108 min_val=Infinite::distance;
00109
00110 collision=false;
00111
00112 float ret_val=
00113 safety->minimum_obstacle_to_arc(tmp,
00114 pcmd.velocity*near_safety_time,
00115 pcmd.yawRate*near_safety_time,
00116 obstacle->lasers->all_obstacle_list,
00117 tmp);
00118 if (Epsilon::equal(ret_val,0.0))
00119 {
00120
00121 collision_obst=true;
00122 collision=true;
00123 result = Beware;
00124 if (pcmd.velocity > safety_speed/near_slow_ratio)
00125 {
00126 if (verbose >= 3)
00127 ART_MSG(2, "Collision potential, multiply by %.3f: "
00128 "from %.3f, %.3f",
00129 near_slow_ratio, pcmd.velocity, pcmd.yawRate);
00130 pcmd.velocity*=near_slow_ratio;
00131
00132 }
00133 else if (pcmd.velocity > safety_speed)
00134 {
00135 float ratio=safety_speed/pcmd.velocity;
00136 if (verbose >= 3)
00137 ART_MSG(2, "Collision potential, multiply by %.3f: "
00138 "from %.3f, %.3f",
00139 ratio, pcmd.velocity, pcmd.yawRate);
00140 pcmd.velocity*=ratio;
00141
00142 }
00143 else
00144 {
00145 return halt_immediately(retpcmd);
00146 }
00147 }
00148 } while (collision);
00149
00150 if (collision_obst)
00151 {
00152 retpcmd=pcmd;
00153 retpcmd.velocity=fabsf(retpcmd.velocity);
00154 trace("safety controller", retpcmd, result);
00155 return result;
00156 }
00157
00158
00159
00160
00161
00162
00163 ret_val=
00164 safety->minimum_obstacle_to_arc(tmp,
00165 pcmd.velocity*(far_safety_time-near_safety_time),
00166 pcmd.yawRate*(far_safety_time-near_safety_time),
00167 obstacle->lasers->all_obstacle_list,
00168 tmp);
00169 if (Epsilon::equal(ret_val,0.0))
00170 {
00171
00172 result = Caution;
00173 if (pcmd.velocity > safety_speed/far_slow_ratio)
00174 {
00175 if (verbose >= 3)
00176 ART_MSG(2, "Danger ahead, slowing by %.3f times: from %.3f, %.3f ",
00177 far_slow_ratio, pcmd.velocity, pcmd.yawRate);
00178 pcmd.velocity=pcmd.velocity*far_slow_ratio;
00179
00180 }
00181 else if (pcmd.velocity > safety_speed)
00182 {
00183 float ratio=safety_speed/pcmd.velocity;
00184 if (verbose >= 3)
00185 ART_MSG(2, "Danger ahead, slowing by %.3f times: from %.3f, %.3f ",
00186 ratio, pcmd.velocity, pcmd.yawRate);
00187 pcmd.velocity=pcmd.velocity*ratio;
00188
00189 }
00190 }
00191 retpcmd=pcmd;
00192 retpcmd.velocity=fabsf(retpcmd.velocity);
00193 trace("safety controller", pcmd, result);
00194 return result;
00195 }
00196
00197
00198
00199
00200
00201
00202 Controller::result_t Safety::halt_immediately(pilot_command_t &pcmd)
00203 {
00204 if (verbose >= 3)
00205 ART_MSG(2, "Collision imminent, halting: from %.3f, %.3f",
00206 pcmd.velocity, pcmd.yawRate);
00207 pcmd.velocity=0.0;
00208
00209
00210
00211 result_t result = Unsafe;
00212 if (navdata->stopped)
00213 result = Blocked;
00214 trace("safety controller", pcmd, result);
00215 return result;
00216 }