Ejemplo n.º 1
0
namespace larcfm {

TCASTable KinematicBandsCore::RA = TCASTable();

KinematicBandsCore::KinematicBandsCore() {
  ownship = OwnshipState::INVALID;
  traffic = std::vector<TrafficState>();
  implicit_bands = DefaultDaidalusParameters::isEnabledImplicitBands();
  lookahead = DefaultDaidalusParameters::getLookaheadTime();
  alerting_time = DefaultDaidalusParameters::getAlertingTime();
  max_recovery_time = DefaultDaidalusParameters::getMaxRecoveryTime();
  recovery_stability_time = DefaultDaidalusParameters::getRecoveryStabilityTime();
  criteria_ac = TrafficState::INVALID.getId();
  conflict_crit = DefaultDaidalusParameters::isEnabledConflictCriteria();
  recovery_crit = DefaultDaidalusParameters::isEnabledRecoveryCriteria();
  min_horizontal_recovery = DefaultDaidalusParameters::getMinHorizontalRecovery();
  min_vertical_recovery = DefaultDaidalusParameters::getMinVerticalRecovery();
  ca_bands = DefaultDaidalusParameters::isEnabledCollisionAvoidanceBands();
  detector = new CDCylinder();
}

KinematicBandsCore::KinematicBandsCore(const Detection3D* det) {
  ownship = OwnshipState::INVALID;
  traffic = std::vector<TrafficState>();
  implicit_bands = DefaultDaidalusParameters::isEnabledImplicitBands();
  lookahead = DefaultDaidalusParameters::getLookaheadTime();
  alerting_time = DefaultDaidalusParameters::getAlertingTime();
  max_recovery_time = DefaultDaidalusParameters::getMaxRecoveryTime();
  recovery_stability_time = DefaultDaidalusParameters::getRecoveryStabilityTime();
  criteria_ac = TrafficState::INVALID.getId();
  conflict_crit = DefaultDaidalusParameters::isEnabledConflictCriteria();
  recovery_crit = DefaultDaidalusParameters::isEnabledRecoveryCriteria();
  min_horizontal_recovery = DefaultDaidalusParameters::getMinHorizontalRecovery();
  min_vertical_recovery = DefaultDaidalusParameters::getMinVerticalRecovery();
  ca_bands = DefaultDaidalusParameters::isEnabledCollisionAvoidanceBands();
  detector = det->copy();
}

KinematicBandsCore::KinematicBandsCore(const KinematicBandsCore& core) {
  ownship = OwnshipState(core.ownship);
  for (int i = 0; i < (int) core.traffic.size(); ++i) {
    TrafficState ac = core.traffic[i];
    traffic.push_back(TrafficState(ac));
  }
  implicit_bands = core.implicit_bands;
  lookahead = core.lookahead;
  alerting_time = core.alerting_time;
  max_recovery_time = core.max_recovery_time;
  recovery_stability_time = core.recovery_stability_time;
  criteria_ac = core.criteria_ac;
  conflict_crit = core.conflict_crit;
  recovery_crit = core.recovery_crit;
  min_horizontal_recovery = core.min_horizontal_recovery;
  min_vertical_recovery = core.min_vertical_recovery;
  ca_bands = core.ca_bands;
  detector = core.detector->copy();
}

KinematicBandsCore::~KinematicBandsCore() {
  delete detector;
}

KinematicBandsCore& KinematicBandsCore::operator=(const KinematicBandsCore& core) {
  ownship = OwnshipState(core.ownship);
  for (int i = 0; i < (int) core.traffic.size(); ++i) {
    TrafficState ac = core.traffic[i];
    traffic.push_back(TrafficState(ac));
  }
  implicit_bands = core.implicit_bands;
  lookahead = core.lookahead;
  alerting_time = core.alerting_time;
  max_recovery_time = core.max_recovery_time;
  recovery_stability_time = core.recovery_stability_time;
  criteria_ac = core.criteria_ac;
  conflict_crit = core.conflict_crit;
  recovery_crit = core.recovery_crit;
  min_horizontal_recovery = core.min_horizontal_recovery;
  min_vertical_recovery = core.min_vertical_recovery;
  ca_bands = core.ca_bands;
  detector = core.detector->copy();
  return *this;
}


/**
 *  Clear ownship and traffic data from this object.
 */
void KinematicBandsCore::clear() {
  ownship = OwnshipState::INVALID;
  traffic.clear();
}

/**
 * Return actual alerting time in seconds.
 */
double KinematicBandsCore::alertingTime() const {
  return alerting_time > 0 ? alerting_time : lookahead;
}

/**
 *  Returns actual maximum recovery time in seconds.
 */
double KinematicBandsCore::maxRecoveryTime() const {
  return max_recovery_time > 0 ? max_recovery_time : lookahead;
}

/**
 * Returns actual minimum horizontal separation for recovery bands in internal units.
 */
double KinematicBandsCore::minHorizontalRecovery() const {
  if (min_horizontal_recovery > 0)
    return min_horizontal_recovery;
  int sl = !hasOwnship() ? 3 : std::max(3,TCASTable::getSensitivityLevel(ownship.getPosition().alt()));
  return RA.getHMD(sl);
}

/**
 * Returns actual minimum vertical separation for recovery bands in internal units.
 */
double KinematicBandsCore::minVerticalRecovery() const {
  if (min_vertical_recovery > 0)
    return min_vertical_recovery;
  int sl = !hasOwnship() ? 3 : std::max(3,TCASTable::getSensitivityLevel(ownship.getPosition().alt()));
  return RA.getZTHR(sl);
}

bool KinematicBandsCore::hasOwnship() const {
  return ownship.isValid();
}

OwnshipState KinematicBandsCore::getOwnship() const {
  return ownship;
}

TrafficState KinematicBandsCore::getTraffic(int i) const {
  return traffic[i];
}

int KinematicBandsCore::trafficSize() const {
  return traffic.size();
}

TrafficState KinematicBandsCore::getTraffic(const std::string& id) const {
  return TrafficState::getTraffic(traffic,id);
}

bool KinematicBandsCore::hasTraffic() const {
  return traffic.size() > 0;
}

double KinematicBandsCore::getRecoveryStabilityTime() const {
  return recovery_stability_time;
}

double KinematicBandsCore::getLookahead() const {
  return lookahead;
}

Position KinematicBandsCore::trafficPosition(int i) const {
  return getTraffic(i).getPosition();
}

Velocity KinematicBandsCore::trafficVelocity(int i) const {
  return getTraffic(i).getVelocity();
}

Vect3 KinematicBandsCore::own_s() const {
  return ownship.get_s();
}

Velocity KinematicBandsCore::own_v() const {
  return ownship.get_v();
}

Vect3 KinematicBandsCore::pos_to_s(const Position& p) const {
  return ownship.pos_to_s(p);
}

Vect3 KinematicBandsCore::traffic_s(int i) const {
  return pos_to_s(trafficPosition(i));
}

Vect3 KinematicBandsCore::traffic_s(const TrafficState& ac) const {
  return pos_to_s(ac.getPosition());
}

Velocity KinematicBandsCore::vel_to_v(const Position& p, const Velocity& v) const {
  return ownship.vel_to_v(p,v);
}

Velocity KinematicBandsCore::traffic_v(int i) const {
  return vel_to_v(trafficPosition(i),trafficVelocity(i));
}

Velocity KinematicBandsCore::traffic_v(const TrafficState& ac) const {
  return vel_to_v(ac.getPosition(),ac.getVelocity());
}

/**
 * Returns true if aircraft are currently in Violation
 */
bool KinematicBandsCore::checkViolation(const TrafficState& ac) const {
  return detector->violation(own_s(),own_v(),traffic_s(ac),traffic_v(ac));
}

/**
 * Returns true if the aircraft will be in Violation within time [B,T]
 */
ConflictData KinematicBandsCore::checkConflict(const TrafficState& ac, double B, double T) const {
  return detector->conflictDetection(own_s(),own_v(),traffic_s(ac),traffic_v(ac),B,T);
}

int KinematicBandsCore::epsilonH(const OwnshipState& ownship, const TrafficState& ac) {
  Position pi = ac.getPosition();
  Velocity vi = ac.getVelocity();
  Vect2 s = ownship.get_s().Sub(ownship.pos_to_s(pi)).vect2();
  Vect2 v = ownship.get_v().Sub(ownship.vel_to_v(pi,vi)).vect2();
  return CriteriaCore::horizontalCoordination(s,v);
}

int KinematicBandsCore::epsilonV(const OwnshipState& ownship, const TrafficState& ac) {
  Position pi = ac.getPosition();
  Velocity vi = ac.getVelocity();
  Vect3 si = ownship.pos_to_s(pi);
  Vect3 s = ownship.get_s().Sub(si);
  return CriteriaCore::verticalCoordinationLoS(s,ownship.get_v(),ownship.vel_to_v(pi,vi),
      ownship.getId(), ac.getId());
}

Detection3D* KinematicBandsCore::getCoreDetectionPtr() const {
  return detector;
}

Detection3D& KinematicBandsCore::getCoreDetectionRef() const {
  return *detector;
}

void KinematicBandsCore::setCoreDetectionPtr(const Detection3D* cd) {
  delete detector;
  detector = cd->copy();
}

void KinematicBandsCore::setCoreDetectionRef(const Detection3D& cd) {
  setCoreDetectionPtr(&cd);
}

}
Ejemplo n.º 2
0
namespace larcfm {

TCASTable KinematicBandsCore::RA = TCASTable();

KinematicBandsCore::KinematicBandsCore(const KinematicBandsParameters& params) {
  ownship = TrafficState::INVALID;
  traffic = std::vector<TrafficState>();
  parameters = KinematicBandsParameters(params);
  most_urgent_ac = TrafficState::INVALID;
  conflict_acs_ = std::vector< std::vector<TrafficState> >();
  tiov_ = std::vector<Interval>();
  current_alert_ = 0;
  reset();
}

KinematicBandsCore::KinematicBandsCore(const KinematicBandsCore& core) {
  setKinematicBandsCore(core);
}

KinematicBandsCore& KinematicBandsCore::operator=(const KinematicBandsCore& core) {
  setKinematicBandsCore(core);
  return *this;
}

KinematicBandsCore::~KinematicBandsCore() {
  clear();
}

/**
 * Set kinematic bands core
 */
void KinematicBandsCore::setKinematicBandsCore(const KinematicBandsCore& core) {
  ownship = core.ownship;
  traffic = std::vector<TrafficState>();
  traffic.insert(traffic.end(),core.traffic.begin(),core.traffic.end());
  parameters = KinematicBandsParameters(core.parameters);
  most_urgent_ac = core.most_urgent_ac;
  conflict_acs_ = std::vector< std::vector<TrafficState> >();
  tiov_ = std::vector<Interval>();
  current_alert_ = 0;
  reset();
}

/**
 *  Clear ownship and traffic data from this object.
 */
void KinematicBandsCore::clear() {
  ownship = TrafficState::INVALID;
  traffic.clear();
  reset();
}

/**
 *  Reset cached values
 */
void KinematicBandsCore::reset() {
  outdated_ = true;
  epsh_ = 0;
  epsv_ = 0;
  tiov_.clear();
  current_alert_ = 0;
}

/**
 *  Update cached values
 */
void KinematicBandsCore::update() {
  if (outdated_) {
    current_alert_ = 0;
    for (int alert_level=1; alert_level <= parameters.alertor.mostSevereAlertLevel(); ++alert_level) {
      if (alert_level-1 >= (int) conflict_acs_.size()) {
        conflict_acs_.push_back(std::vector<TrafficState>());
      } else {
        conflict_acs_[alert_level-1].clear();
      }
      conflict_aircraft(alert_level);
      if (!conflict_acs_[alert_level-1].empty()) {
        current_alert_ = alert_level;
      }
    }
    epsh_ = epsilonH(ownship,most_urgent_ac);
    epsv_ = epsilonV(ownship,most_urgent_ac);
    outdated_ = false;
  }
}

/**
 * Returns current alert level
 */
int KinematicBandsCore::currentAlertLevel() {
  update();
  return current_alert_;
}

/**
 *  Returns horizontal epsilon for implicit coordination with respect to criteria ac
 */
int KinematicBandsCore::epsilonH() {
  update();
  return epsh_;
}

/**
 *  Returns vertical epsilon for implicit coordination with respect to criteria ac
 */
int KinematicBandsCore::epsilonV() {
  update();
  return epsv_;
}

/**
 * Returns actual minimum horizontal separation for recovery bands in internal units.
 */
double KinematicBandsCore::minHorizontalRecovery() const {
  double min_horizontal_recovery = parameters.getMinHorizontalRecovery();
  if (min_horizontal_recovery > 0)
    return min_horizontal_recovery;
  int sl = !hasOwnship() ? 3 : Util::max(3,TCASTable::getSensitivityLevel(ownship.altitude()));
  return RA.getHMD(sl);
}

/**
 * Returns actual minimum vertical separation for recovery bands in internal units.
 */
double KinematicBandsCore::minVerticalRecovery() const {
  double min_vertical_recovery = parameters.getMinVerticalRecovery();
  if (min_vertical_recovery > 0)
    return min_vertical_recovery;
  int sl = !hasOwnship() ? 3 : Util::max(3,TCASTable::getSensitivityLevel(ownship.altitude()));
  return RA.getZTHR(sl);
}

bool KinematicBandsCore::hasOwnship() const {
  return ownship.isValid();
}

TrafficState KinematicBandsCore::intruder(const std::string& id) const {
  return TrafficState::findAircraft(traffic,id);
}

bool KinematicBandsCore::hasTraffic() const {
  return traffic.size() > 0;
}

/**
 * Put in conflict_acs_ the list of aircraft predicted to be in conflict for the given alert level.
 * Requires: 1 <= alert_level <= parameters.alertor.mostSevereAlertLevel()
 */
void KinematicBandsCore::conflict_aircraft(int alert_level) {
  double tin  = PINFINITY;
  double tout = NINFINITY;
  bool conflict_band = BandsRegion::isConflictBand(parameters.alertor.getLevel(alert_level).getRegion());
  Detection3D* detector = parameters.alertor.getLevel(alert_level).getDetectorRef();
  double alerting_time = Util::min(parameters.getLookaheadTime(),
      parameters.alertor.getLevel(alert_level).getAlertingTime());
  for (TrafficState::nat i = 0; i < traffic.size(); ++i) {
    TrafficState ac = traffic[i];
    ConflictData det = detector->conflictDetection(ownship.get_s(),ownship.get_v(),ac.get_s(),ac.get_v(),
        0,parameters.getLookaheadTime());
    bool lowc = detector->violation(ownship.get_s(),ownship.get_v(),ac.get_s(),ac.get_v());
    if (lowc || det.conflict()) {
      if (conflict_band && (lowc || det.getTimeIn() < alerting_time)) {
        conflict_acs_[alert_level-1].push_back(ac);
      }
      tin = Util::min(tin,det.getTimeIn());
      tout = Util::max(tout,det.getTimeOut());
    }
  }
  tiov_.push_back(Interval(tin,tout));
}

/**
 * Return list of conflict aircraft for a given alert level.
 * Requires: 1 <= alert_level <= parameters.alertor.mostSevereAlertLevel()
 */
std::vector<TrafficState> const & KinematicBandsCore::conflictAircraft(int alert_level) {
  update();
  if (alert_level >= 1 && alert_level <= parameters.alertor.mostSevereAlertLevel()) {
    return conflict_acs_[alert_level-1];
  }
  return TrafficState::INVALIDL;
}

/**
 * Return time interval of violation for given alert level
 * Requires: 1 <= alert_level <= alertor.mostSevereAlertLevel()
 */
Interval const & KinematicBandsCore::timeIntervalOfViolation(int alert_level) {
  update();
  if (alert_level >= 1 && alert_level <= parameters.alertor.mostSevereAlertLevel()) {
    return tiov_[alert_level-1];
  }
  return Interval::EMPTY;
}

int KinematicBandsCore::epsilonH(const TrafficState& ownship, const TrafficState& ac) {
  if (ownship.isValid() && ac.isValid()) {
    Vect2 s = ownship.get_s().Sub(ac.get_s()).vect2();
    Vect2 v = ownship.get_v().Sub(ac.get_v()).vect2();
    return CriteriaCore::horizontalCoordination(s,v);
  } else {
    return 0;
  }
}

int KinematicBandsCore::epsilonV(const TrafficState& ownship, const TrafficState& ac) {
  if (ownship.isValid() && ac.isValid()) {
    Vect3 s = ownship.get_s().Sub(ac.get_s());
    return CriteriaCore::verticalCoordinationLoS(s,ownship.get_v(),ac.get_v(),
        ownship.getId(), ac.getId());
  } else {
    return 0;
  }
}

TrafficState const & KinematicBandsCore::criteria_ac() const {
  return parameters.isEnabledConflictCriteria() ? most_urgent_ac : TrafficState::INVALID;
}

TrafficState const & KinematicBandsCore::recovery_ac() const {
  return parameters.isEnabledRecoveryCriteria() ? most_urgent_ac : TrafficState::INVALID;
}

std::string KinematicBandsCore::toString() const {
  int precision = Constants::get_output_precision();
  std::string s="";
  s+="## KinematicBandsCore Parameters\n";
  s+=parameters.toString();
  s+="## KinematicBandsCore Internals\n";
  s+="outdated_ = "+Fmb(outdated_)+"\n";
  s+="most_urgent_ac_ = "+most_urgent_ac.getId()+"\n";
  s+="epsh_ = "+Fmi(epsh_)+"\n";
  s+="epsv_ = "+Fmi(epsv_)+"\n";
  for (TrafficState::nat i=0; i < conflict_acs_.size(); ++i) {
    s+="conflict_acs_["+Fmi(i)+"]: "+
        TrafficState::listToString(conflict_acs_[i])+"\n";
  }
  for (Interval::nat i=0; i < tiov_.size(); ++i) {
    s+="tiov_["+Fmi(i)+"]: "+
        tiov_[i].toString(precision)+"\n";
  }
  s+="## Ownship and Traffic\n";
  s+="NAME sx sy sz vx vy vz time\n";
  s+="[none] [m] [m] [m] [m/s] [m/s] [m/s] [s]\n";
  s+=ownship.getId()+", "+ownship.get_s().formatXYZ(precision,"",", ","")+
      ", "+ownship.get_v().formatXYZ(precision,"",", ","")+", "+
      FmPrecision(ownship.getTime(),precision)+"\n";
  for (TrafficState::nat i = 0; i < traffic.size(); i++) {
    s+=traffic[i].getId()+", "+traffic[i].get_s().formatXYZ(precision,"",", ","")+
        ", "+traffic[i].get_v().formatXYZ(precision,"",", ","")+
        ", "+FmPrecision(traffic[i].getTime(),precision)+"\n";
  }
  s+="##\n";
  return s;

}

}