コード例 #1
0
inline void
GlideComputerAirData::NextLegEqThermal(const NMEAInfo &basic,
                                       DerivedInfo &calculated,
                                       const ComputerSettings &settings)
{
  const GeoVector vector_remaining =
      calculated.task_stats.current_leg.vector_remaining;
  const GeoVector next_leg_vector =
      calculated.task_stats.current_leg.next_leg_vector;

  if(!next_leg_vector.IsValid() ||
      !vector_remaining.IsValid() ||
      !calculated.wind_available) {
    // Assign a negative value to invalidate the result
    calculated.next_leg_eq_thermal = fixed(-1);
    return;
  }

  // Calculate wind component on current and next legs
  const fixed wind_comp = calculated.wind.norm *
      (calculated.wind.bearing - vector_remaining.bearing).fastcosine();
  const fixed next_comp = calculated.wind.norm *
      (calculated.wind.bearing - next_leg_vector.bearing).fastcosine();

  calculated.next_leg_eq_thermal =
      settings.polar.glide_polar_task.GetNextLegEqThermal(wind_comp, next_comp);
}
コード例 #2
0
ファイル: Task.cpp プロジェクト: Adrien81/XCSoar
void
UpdateInfoBoxNextDistanceNominal(InfoBoxData &data)
{
  const Waypoint* way_point = protected_task_manager != NULL
    ? protected_task_manager->GetActiveWaypoint()
    : NULL;

  if (!way_point) {
    data.SetInvalid();
    return;
  }

  const NMEAInfo &basic = CommonInterface::Basic();
  const TaskStats &task_stats = CommonInterface::Calculated().task_stats;

  if (!task_stats.task_valid || !basic.location_available) {
      data.SetInvalid();
      return;
  }

  const GeoVector vector(basic.location, way_point->location);

  if (!vector.IsValid()) {
      data.SetInvalid();
      return;
  }

  // Set Value
  data.SetValueFromDistance(vector.distance);
  data.SetValueColor(task_stats.inside_oz ? 3 : 0);
  data.SetComment(vector.bearing);
}
コード例 #3
0
static int
ShowMapItemListDialog(SingleWindow &parent)
{
  unsigned num_items = list->size();

  UPixelScalar item_height = Fonts::map_bold.GetHeight() + Layout::Scale(6) +
                             Fonts::map_label.GetHeight();

  assert(num_items <= 0x7fffffff);
  assert(item_height > 0);

  wf = LoadDialog(CallBackTable, parent, Layout::landscape ?
                  _T("IDR_XML_MAPITEMLIST_L") : _T("IDR_XML_MAPITEMLIST"));
  assert(wf != NULL);

  details_button = (WndButton *)wf->FindByName(_T("cmdDetails"));
  assert(details_button);

  WndListFrame *list_control =
      (WndListFrame *)wf->FindByName(_T("frmComboPopupList"));
  assert(list_control != NULL);
  list_control->SetItemHeight(item_height);
  list_control->SetLength(num_items);
  list_control->SetCursorIndex(0);
  list_control->SetActivateCallback(OnComboPopupListEnter);
  list_control->SetPaintItemCallback(PaintListItem);
  list_control->SetCursorCallback(OnListIndexChange);
  OnListIndexChange(0);

  WndFrame *info_label = (WndFrame *)wf->FindByName(_T("lblInfo"));
  assert(info_label);
  info_label->SetAlignCenter();
  info_label->SetVAlignCenter();

  TCHAR info_buffer[256], distance_buffer[32], direction_buffer[32];
  if (vector.IsValid()) {
    Units::FormatUserDistance(vector.distance, distance_buffer, 32);
    FormatBearing(direction_buffer, ARRAY_SIZE(direction_buffer),
                  vector.bearing, _T("T"));
    _stprintf(info_buffer, _T("%s: %s - %s: %s"),
              _("Distance"), distance_buffer,
              _("Direction"), direction_buffer);
  } else {
    _stprintf(info_buffer, _T("%s: %s - %s: %s"),
              _("Distance"), _T("???"), _("Direction"), _T("???"));
  }

  TCHAR elevation_buffer[32];
  if (elevation != RasterBuffer::TERRAIN_INVALID) {
    Units::FormatUserAltitude(fixed(elevation), elevation_buffer, 32);
    _stprintf(info_buffer + _tcslen(info_buffer), _T(" - %s: %s"),
              _("Elevation"), elevation_buffer);
  }

  AnyCanvas canvas;
  canvas.Select(info_label->GetFont());
  UPixelScalar text_width = canvas.CalcTextWidth(info_buffer);
  if (text_width > info_label->get_width()) {
    if (vector.IsValid())
      _stprintf(info_buffer, _T("%s - %s"), distance_buffer, direction_buffer);
    else
      _stprintf(info_buffer, _T("%s - %s"), _T("???"), _T("???"));

    if (elevation != RasterBuffer::TERRAIN_INVALID)
      _stprintf(info_buffer + _tcslen(info_buffer), _T(" - %s"), elevation_buffer);
  }

  info_label->SetCaption(info_buffer);

  int result = wf->ShowModal() == mrOK
    ? (int)list_control->GetCursorIndex()
    : -1;
  delete wf;

  return result;
}
コード例 #4
0
ファイル: Task.cpp プロジェクト: Advi42/XCSoar
static int
l_task_index(lua_State *L)
{
  const char *name = lua_tostring(L, 2);
  if (name == nullptr)
    return 0;
  else if (StringIsEqual(name, "bearing")) {
    const TaskStats &task_stats = CommonInterface::Calculated().task_stats;
    const GeoVector &vector_remaining = task_stats.current_leg.vector_remaining;
    if (!task_stats.task_valid || !vector_remaining.IsValid() ||
        vector_remaining.distance <= 10) {
      return 0;
    }
    Lua::Push(L, vector_remaining.bearing);
  } else if (StringIsEqual(name, "bearing_diff")) {
      const NMEAInfo &basic = CommonInterface::Basic();
      const TaskStats &task_stats = CommonInterface::Calculated().task_stats;
      const GeoVector &vector_remaining = task_stats.current_leg.vector_remaining;
      if (!basic.track_available || !task_stats.task_valid ||
          !vector_remaining.IsValid() || vector_remaining.distance <= 10) {
        return 0;
      }      
      Lua::Push(L, vector_remaining.bearing - basic.track);
  } else if (StringIsEqual(name, "radial")) {
      const TaskStats &task_stats = CommonInterface::Calculated().task_stats;
      const GeoVector &vector_remaining = task_stats.current_leg.vector_remaining;
      if (!task_stats.task_valid || !vector_remaining.IsValid() ||
          vector_remaining.distance <= 10) {
        return 0;
      }
      Lua::Push(L, vector_remaining.bearing.Reciprocal());
  } else if (StringIsEqual(name, "next_distance")) {
      const TaskStats &task_stats = CommonInterface::Calculated().task_stats;
      const GeoVector &vector_remaining = task_stats.current_leg.vector_remaining;
      if (!task_stats.task_valid || !vector_remaining.IsValid()) 
        return 0;
     
      Lua::Push(L, vector_remaining.distance);
  } else if (StringIsEqual(name, "next_distance_nominal")) {
      const auto way_point = protected_task_manager != nullptr
          ? protected_task_manager->GetActiveWaypoint() : NULL;

      if (!way_point) return 0;
      const NMEAInfo &basic = CommonInterface::Basic();
      const TaskStats &task_stats = CommonInterface::Calculated().task_stats;

      if (!task_stats.task_valid || !basic.location_available) return 0;

      const GeoVector vector(basic.location, way_point->location);

      if (!vector.IsValid()) return 0;
      Lua::Push(L, vector.distance);
  } else if (StringIsEqual(name, "next_ete")) {
      const TaskStats &task_stats = CommonInterface::Calculated().task_stats;
      if (!task_stats.task_valid || !task_stats.current_leg.IsAchievable()) 
        return 0; 
      assert(task_stats.current_leg.time_remaining_now >= 0);

      Lua::Push(L, task_stats.current_leg.time_remaining_now);
  } else if (StringIsEqual(name, "next_eta")) {
      const auto &task_stats = CommonInterface::Calculated().task_stats;
      const BrokenTime &now_local = CommonInterface::Calculated().date_time_local;

      if (!task_stats.task_valid || !task_stats.current_leg.IsAchievable() ||
          !now_local.IsPlausible()) {
        return 0;
      }

      const BrokenTime t = now_local +
      unsigned(task_stats.current_leg.solution_remaining.time_elapsed);
      float time = t.hour + (float)(t.second/60);

      Lua::Push(L, time);
  } else if (StringIsEqual(name, "next_altitude_diff")) {    
      const auto &task_stats = CommonInterface::Calculated().task_stats;
      const auto &next_solution = task_stats.current_leg.solution_remaining;

      if (!task_stats.task_valid || !next_solution.IsAchievable())
        return 0;

      const auto &settings = CommonInterface::GetComputerSettings();
      auto altitude_difference = next_solution.SelectAltitudeDifference(settings.task.glide);
      Lua::Push(L, altitude_difference);
  } else if (StringIsEqual(name, "nextmc0_altitude_diff")) {
      const TaskStats &task_stats = CommonInterface::Calculated().task_stats;
      if (!task_stats.task_valid || !task_stats.current_leg.solution_mc0.IsAchievable())
        return 0;

      const auto &settings = CommonInterface::GetComputerSettings();
      auto altitude_difference = task_stats.current_leg.solution_mc0.SelectAltitudeDifference(settings.task.glide);
      Lua::Push(L, altitude_difference);
  } else if (StringIsEqual(name, "next_altitude_require")) {
      const auto &task_stats = CommonInterface::Calculated().task_stats;
      const auto &next_solution = task_stats.current_leg.solution_remaining;
      if (!task_stats.task_valid || !next_solution.IsAchievable()) 
        return 0;

      Lua::Push(L, next_solution.GetRequiredAltitude());
  } else if (StringIsEqual(name, "next_altitude_arrival")) {
      const auto &basic = CommonInterface::Basic();
      const auto &task_stats = CommonInterface::Calculated().task_stats;
      const auto next_solution = task_stats.current_leg.solution_remaining;
      if (!basic.NavAltitudeAvailable() ||
          !task_stats.task_valid || !next_solution.IsAchievable()) {
        return 0;
      }

      Lua::Push(L, next_solution.GetArrivalAltitude(basic.nav_altitude));
  } else if (StringIsEqual(name, "next_gr")) {
      if (!CommonInterface::Calculated().task_stats.task_valid) 
        return 0;

      auto gradient = CommonInterface::Calculated().task_stats.current_leg.gradient;
      if (gradient <= 0) 
        return 0;     
      if (::GradientValid(gradient)) 
        Lua::Push(L, gradient);
      else 
        return 0;         
  } else if (StringIsEqual(name, "final_distance")) {
      const auto &calculated = CommonInterface::Calculated();
      const TaskStats &task_stats = calculated.task_stats;

      if (!task_stats.task_valid ||
          !task_stats.current_leg.vector_remaining.IsValid() ||
          !task_stats.total.remaining.IsDefined()) {
        return 0;
      }

      Lua::Push(L, task_stats.total.remaining.GetDistance());
  } else if (StringIsEqual(name, "final_ete")) {
      const TaskStats &task_stats = CommonInterface::Calculated().task_stats;

      if (!task_stats.task_valid || !task_stats.total.IsAchievable()) 
        return 0;
      assert(task_stats.total.time_remaining_now >= 0);

      Lua::Push(L, task_stats.total.time_remaining_now);
  } else if (StringIsEqual(name, "final_eta")) {
      const TaskStats &task_stats = CommonInterface::Calculated().task_stats;
      const BrokenTime &now_local = CommonInterface::Calculated().date_time_local;

      if (!task_stats.task_valid || !task_stats.total.IsAchievable() ||
          !now_local.IsPlausible()) 
        return 0;    

      const BrokenTime t = now_local +
        unsigned(task_stats.total.solution_remaining.time_elapsed);

      float time = t.hour + (float)(t.minute/60);
      Lua::Push(L, time);
  } else if (StringIsEqual(name, "final_altitude_diff")) {
      const TaskStats &task_stats = CommonInterface::Calculated().task_stats;
      const auto &settings = CommonInterface::GetComputerSettings();
      if (!task_stats.task_valid || !task_stats.total.solution_remaining.IsAchievable())
        return 0;
      auto altitude_difference =
        task_stats.total.solution_remaining.SelectAltitudeDifference(settings.task.glide);

      Lua::Push(L, altitude_difference);
  } else if (StringIsEqual(name, "finalmc0_altitude_diff")) {
      const TaskStats &task_stats = CommonInterface::Calculated().task_stats;
      const auto &settings = CommonInterface::GetComputerSettings();
      if (!task_stats.task_valid || !task_stats.total.solution_mc0.IsAchievable())
        return 0;
      auto altitude_difference =
        task_stats.total.solution_mc0.SelectAltitudeDifference(settings.task.glide);

      Lua::Push(L, altitude_difference);
  } else if (StringIsEqual(name, "final_altitude_require")) {
      const TaskStats &task_stats = CommonInterface::Calculated().task_stats;
      if (!task_stats.task_valid ||
          !task_stats.total.solution_remaining.IsOk()) {
        return 0;
      }
   
      Lua::Push(L, task_stats.total.solution_remaining.GetRequiredAltitude());
  } else if (StringIsEqual(name, "task_speed")) {
      const TaskStats &task_stats = CommonInterface::Calculated().task_stats;
      if (!task_stats.task_valid || !task_stats.total.travelled.IsDefined()) 
        return 0;

      Lua::Push(L, task_stats.total.travelled.GetSpeed());
  } else if (StringIsEqual(name, "task_speed_achieved")) {
      const TaskStats &task_stats = CommonInterface::Calculated().task_stats;
      if (!task_stats.task_valid || !task_stats.total.remaining_effective.IsDefined()) 
        return 0;

      Lua::Push(L, task_stats.total.remaining_effective.GetSpeed());
  } else if (StringIsEqual(name, "task_speed_instant")) {
      const TaskStats &task_stats = CommonInterface::Calculated().task_stats;
      if (!task_stats.task_valid)
        return -1;

      Lua::Push(L, task_stats.inst_speed_fast);
  } else if (StringIsEqual(name, "task_speed_hour")) {
      const WindowStats &window = CommonInterface::Calculated().task_stats.last_hour;
      if (window.duration < 0)
        return 0;

      Lua::Push(L, window.speed);
  } else if (StringIsEqual(name, "final_gr")) {
      const TaskStats &task_stats = CommonInterface::Calculated().task_stats;
      if (!task_stats.task_valid) 
        return 0;

      auto gradient = task_stats.total.gradient;

      if (gradient <= 0)
        return 0;
      if (::GradientValid(gradient))
        Lua::Push(L, gradient);
      else
        return 0;
  } else if (StringIsEqual(name, "aat_time")) {
      const auto &calculated = CommonInterface::Calculated();
      const TaskStats &task_stats = calculated.ordered_task_stats;
      const CommonStats &common_stats = calculated.common_stats;

      if (!task_stats.has_targets || !task_stats.total.IsAchievable()) 
        return 0;

      Lua::Push(L, common_stats.aat_time_remaining);
  } else if (StringIsEqual(name, "aat_time_delta")) {
      const auto &calculated = CommonInterface::Calculated();
      const TaskStats &task_stats = calculated.ordered_task_stats;
      const CommonStats &common_stats = calculated.common_stats;
      if (!task_stats.has_targets || !task_stats.total.IsAchievable()) 
        return 0;
   
      assert(task_stats.total.time_remaining_start >= 0);

      auto diff = task_stats.total.time_remaining_start -
        common_stats.aat_time_remaining;

      Lua::Push(L, diff);
  } else if (StringIsEqual(name, "aat_distance")) {
      const auto &calculated = CommonInterface::Calculated();
      const TaskStats &task_stats = calculated.ordered_task_stats;

      if (!task_stats.has_targets || !task_stats.total.planned.IsDefined()) 
        return 0;
       
      Lua::Push(L, task_stats.total.planned.GetDistance());
  } else if (StringIsEqual(name, "aat_distance_max")) {
      const auto &calculated = CommonInterface::Calculated();
      const TaskStats &task_stats = calculated.ordered_task_stats;

      if (!task_stats.has_targets) 
        return 0;

      Lua::Push(L, task_stats.distance_max);
  } else if (StringIsEqual(name, "aat_distance_min")) {
      const auto &calculated = CommonInterface::Calculated();
      const TaskStats &task_stats = calculated.ordered_task_stats;

      if (!task_stats.has_targets) 
        return 0;

      Lua::Push(L, task_stats.distance_min);
  } else if (StringIsEqual(name, "aat_speed")) {
      const auto &calculated = CommonInterface::Calculated();
      const TaskStats &task_stats = calculated.ordered_task_stats;
      const CommonStats &common_stats = calculated.common_stats;

      if (!task_stats.has_targets || common_stats.aat_speed_target <= 0) 
        return 0;

      Lua::Push(L, common_stats.aat_speed_target);
  } else if (StringIsEqual(name, "aat_speed_max")) {
      const auto &calculated = CommonInterface::Calculated();
      const TaskStats &task_stats = calculated.ordered_task_stats;
      const CommonStats &common_stats = calculated.common_stats;

      if (!task_stats.has_targets || common_stats.aat_speed_max <= 0) 
        return 0;

      Lua::Push(L, common_stats.aat_speed_max);
  } else if (StringIsEqual(name, "aat_speed_min")) {
      const auto &calculated = CommonInterface::Calculated();
      const TaskStats &task_stats = calculated.ordered_task_stats;
      const CommonStats &common_stats = calculated.common_stats;

      if (!task_stats.has_targets ||
        !task_stats.task_valid || common_stats.aat_speed_min <= 0) 
        return 0;
    
      Lua::Push(L, common_stats.aat_speed_min);
  } else if (StringIsEqual(name, "time_under_max_height")) {
      const auto &calculated = CommonInterface::Calculated();
      const auto &task_stats = calculated.ordered_task_stats;
      const auto &common_stats = calculated.common_stats;
      const double maxheight = protected_task_manager->GetOrderedTaskSettings().start_constraints.max_height;

      if (!task_stats.task_valid || maxheight <= 0
          || !protected_task_manager
          || common_stats.TimeUnderStartMaxHeight <= 0) {
        return 0;
      }
      const int time = (int)(CommonInterface::Basic().time -
      common_stats.TimeUnderStartMaxHeight);

      Lua::Push(L, time);
  } else if (StringIsEqual(name, "next_etevmg")) {
      const NMEAInfo &basic = CommonInterface::Basic();
      const TaskStats &task_stats = CommonInterface::Calculated().task_stats;

      if (!basic.ground_speed_available || !task_stats.task_valid ||
          !task_stats.current_leg.remaining.IsDefined()) {  
        return 0;
      }
      const auto d = task_stats.current_leg.remaining.GetDistance();
      const auto v = basic.ground_speed;

      if (!task_stats.task_valid ||
          d <= 0 ||
          v <= 0) {
        return 0;
      }
   
      Lua::Push(L, d/v);
  } else if (StringIsEqual(name, "final_etevmg")) {
      const NMEAInfo &basic = CommonInterface::Basic();
      const TaskStats &task_stats = CommonInterface::Calculated().task_stats;

      if (!basic.ground_speed_available || !task_stats.task_valid ||
          !task_stats.total.remaining.IsDefined()) {
        return 0;
      }
      const auto d = task_stats.total.remaining.GetDistance();
      const auto v = basic.ground_speed;

      if (!task_stats.task_valid ||
          d <= 0 ||
          v <= 0) {
        return 0;
      }
 
      Lua::Push(L, d/v);
  } else if (StringIsEqual(name, "cruise_efficiency")) {
      const TaskStats &task_stats = CommonInterface::Calculated().task_stats;
      if (!task_stats.task_valid || !task_stats.start.task_started) 
        return 0;

      Lua::Push(L, task_stats.cruise_efficiency);
  } else
    return 0;

  return 1;
}