Endurance view
This commit is contained in:
		@ -0,0 +1,39 @@
 | 
			
		||||
#ifndef ENDURANCEPRESENTER_HPP
 | 
			
		||||
#define ENDURANCEPRESENTER_HPP
 | 
			
		||||
 | 
			
		||||
#include <gui/model/ModelListener.hpp>
 | 
			
		||||
#include <mvp/Presenter.hpp>
 | 
			
		||||
 | 
			
		||||
using namespace touchgfx;
 | 
			
		||||
 | 
			
		||||
class EnduranceView;
 | 
			
		||||
 | 
			
		||||
class EndurancePresenter : public touchgfx::Presenter, public ModelListener {
 | 
			
		||||
public:
 | 
			
		||||
  EndurancePresenter(EnduranceView &v);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The activate function is called automatically when this screen is "switched
 | 
			
		||||
   * in" (ie. made active). Initialization logic can be placed here.
 | 
			
		||||
   */
 | 
			
		||||
  virtual void activate() override;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The deactivate function is called automatically when this screen is
 | 
			
		||||
   * "switched out" (ie. made inactive). Teardown functionality can be placed
 | 
			
		||||
   * here.
 | 
			
		||||
   */
 | 
			
		||||
  virtual void deactivate() override;
 | 
			
		||||
 | 
			
		||||
  virtual ~EndurancePresenter() {}
 | 
			
		||||
 | 
			
		||||
  void vehicleStateUpdated() override;
 | 
			
		||||
  void nextScreen() override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  EndurancePresenter();
 | 
			
		||||
 | 
			
		||||
  EnduranceView &view;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // ENDURANCEPRESENTER_HPP
 | 
			
		||||
							
								
								
									
										71
									
								
								TouchGFX/gui/include/gui/endurance_screen/EnduranceView.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								TouchGFX/gui/include/gui/endurance_screen/EnduranceView.hpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,71 @@
 | 
			
		||||
#ifndef ENDURANCEVIEW_HPP
 | 
			
		||||
#define ENDURANCEVIEW_HPP
 | 
			
		||||
 | 
			
		||||
#include "touchgfx/Unicode.hpp"
 | 
			
		||||
#include "touchgfx/widgets/BoxWithBorder.hpp"
 | 
			
		||||
#include "touchgfx/widgets/TextAreaWithWildcard.hpp"
 | 
			
		||||
#include <cstddef>
 | 
			
		||||
#include <gui/endurance_screen/EndurancePresenter.hpp>
 | 
			
		||||
#include <gui_generated/endurance_screen/EnduranceViewBase.hpp>
 | 
			
		||||
 | 
			
		||||
class BatDelta {
 | 
			
		||||
public:
 | 
			
		||||
  BatDelta(touchgfx::BoxWithBorder &box,
 | 
			
		||||
           touchgfx::TextAreaWithOneWildcard &field);
 | 
			
		||||
 | 
			
		||||
  void setBox(touchgfx::BoxWithBorder &box);
 | 
			
		||||
  void setField(touchgfx::TextAreaWithOneWildcard &field);
 | 
			
		||||
  void setDelta(float delta);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
  touchgfx::BoxWithBorder &box;
 | 
			
		||||
  touchgfx::TextAreaWithOneWildcard &field;
 | 
			
		||||
 | 
			
		||||
  touchgfx::Unicode::UnicodeChar buffer[16];
 | 
			
		||||
 | 
			
		||||
  int value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class ValueBuffer {
 | 
			
		||||
public:
 | 
			
		||||
  ValueBuffer(touchgfx::TextAreaWithOneWildcard &field, size_t intDigits,
 | 
			
		||||
              size_t decimalDigits);
 | 
			
		||||
 | 
			
		||||
  void setField(touchgfx::TextAreaWithOneWildcard &field);
 | 
			
		||||
  void setIntValue(int value);
 | 
			
		||||
  void setFloatValue(float value);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
  touchgfx::TextAreaWithOneWildcard &field;
 | 
			
		||||
 | 
			
		||||
  touchgfx::Unicode::UnicodeChar buffer[16];
 | 
			
		||||
 | 
			
		||||
  size_t intDigits;
 | 
			
		||||
  size_t decimalDigits;
 | 
			
		||||
 | 
			
		||||
  union {
 | 
			
		||||
    int i;
 | 
			
		||||
    float f;
 | 
			
		||||
  } value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class EnduranceView : public EnduranceViewBase {
 | 
			
		||||
public:
 | 
			
		||||
  EnduranceView();
 | 
			
		||||
  virtual ~EnduranceView() {}
 | 
			
		||||
  virtual void setupScreen() override;
 | 
			
		||||
  virtual void tearDownScreen() override;
 | 
			
		||||
 | 
			
		||||
  void updateBatDelta();
 | 
			
		||||
  void updateDetails();
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
  BatDelta lastLapDelta;
 | 
			
		||||
  BatDelta overallDelta;
 | 
			
		||||
  ValueBuffer plimBuffer;
 | 
			
		||||
  ValueBuffer slimBuffer;
 | 
			
		||||
  ValueBuffer socBuffer;
 | 
			
		||||
  ValueBuffer tbatBuffer;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // ENDURANCEVIEW_HPP
 | 
			
		||||
							
								
								
									
										20
									
								
								TouchGFX/gui/src/endurance_screen/EndurancePresenter.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								TouchGFX/gui/src/endurance_screen/EndurancePresenter.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
#include "gui/common/FrontendApplication.hpp"
 | 
			
		||||
#include "touchgfx/Application.hpp"
 | 
			
		||||
#include <gui/endurance_screen/EndurancePresenter.hpp>
 | 
			
		||||
#include <gui/endurance_screen/EnduranceView.hpp>
 | 
			
		||||
 | 
			
		||||
EndurancePresenter::EndurancePresenter(EnduranceView &v) : view(v) {}
 | 
			
		||||
 | 
			
		||||
void EndurancePresenter::activate() {}
 | 
			
		||||
 | 
			
		||||
void EndurancePresenter::deactivate() {}
 | 
			
		||||
 | 
			
		||||
void EndurancePresenter::vehicleStateUpdated() {
 | 
			
		||||
  view.updateBatDelta();
 | 
			
		||||
  view.updateDetails();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void EndurancePresenter::nextScreen() {
 | 
			
		||||
  static_cast<FrontendApplication *>(Application::getInstance())
 | 
			
		||||
      ->gotoDriverViewScreenNoTransition();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										119
									
								
								TouchGFX/gui/src/endurance_screen/EnduranceView.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								TouchGFX/gui/src/endurance_screen/EnduranceView.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,119 @@
 | 
			
		||||
#include "touchgfx/Color.hpp"
 | 
			
		||||
#include "touchgfx/Unicode.hpp"
 | 
			
		||||
#include "vehicle_state.h"
 | 
			
		||||
#include <climits>
 | 
			
		||||
#include <cmath>
 | 
			
		||||
#include <gui/endurance_screen/EnduranceView.hpp>
 | 
			
		||||
 | 
			
		||||
EnduranceView::EnduranceView()
 | 
			
		||||
    : lastLapDelta(lastLapBox, lastLapBat),
 | 
			
		||||
      overallDelta(overallBox, overallBat), plimBuffer(powerLimit, 2, 0),
 | 
			
		||||
      slimBuffer(speedLimit, 2, 0), socBuffer(soc, 3, 0),
 | 
			
		||||
      tbatBuffer(batTemp, 2, 1) {}
 | 
			
		||||
 | 
			
		||||
void EnduranceView::setupScreen() {
 | 
			
		||||
  EnduranceViewBase::setupScreen();
 | 
			
		||||
  lastLapDelta.setField(lastLapBat);
 | 
			
		||||
  lastLapDelta.setBox(lastLapBox);
 | 
			
		||||
  overallDelta.setField(overallBat);
 | 
			
		||||
  overallDelta.setBox(overallBox);
 | 
			
		||||
  plimBuffer.setField(powerLimit);
 | 
			
		||||
  slimBuffer.setField(speedLimit);
 | 
			
		||||
  socBuffer.setField(soc);
 | 
			
		||||
  tbatBuffer.setField(batTemp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void EnduranceView::tearDownScreen() { EnduranceViewBase::tearDownScreen(); }
 | 
			
		||||
 | 
			
		||||
void EnduranceView::updateBatDelta() {
 | 
			
		||||
  lastLapDelta.setDelta(vehicle_state.bat_delta_last);
 | 
			
		||||
  overallDelta.setDelta(vehicle_state.bat_delta_overall);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void EnduranceView::updateDetails() {
 | 
			
		||||
  plimBuffer.setIntValue(vehicle_state.power_limit);
 | 
			
		||||
  slimBuffer.setIntValue(vehicle_state.speed_limit);
 | 
			
		||||
  socBuffer.setIntValue(vehicle_state.soc_ts);
 | 
			
		||||
  tbatBuffer.setFloatValue(vehicle_state.max_cell_temp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BatDelta::BatDelta(touchgfx::BoxWithBorder &box,
 | 
			
		||||
                   touchgfx::TextAreaWithOneWildcard &field)
 | 
			
		||||
    : box(box), field(field), value(INT_MIN) {}
 | 
			
		||||
 | 
			
		||||
void BatDelta::setField(touchgfx::TextAreaWithOneWildcard &field) {
 | 
			
		||||
  this->field = field;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BatDelta::setBox(touchgfx::BoxWithBorder &box) { this->box = box; }
 | 
			
		||||
 | 
			
		||||
void BatDelta::setDelta(float delta) {
 | 
			
		||||
  int deltaRounded = std::round(delta);
 | 
			
		||||
  if (deltaRounded == value) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  value = deltaRounded;
 | 
			
		||||
 | 
			
		||||
  touchgfx::Unicode::snprintf(buffer, sizeof(buffer) / sizeof(*buffer), "%+3d",
 | 
			
		||||
                              value);
 | 
			
		||||
  field.setWildcard(buffer);
 | 
			
		||||
  field.invalidate();
 | 
			
		||||
 | 
			
		||||
  if (value > 10) {
 | 
			
		||||
    box.setColor(touchgfx::Color::getColorFromRGB(0xa8, 0x08, 0x08));
 | 
			
		||||
  } else if (value > 5) {
 | 
			
		||||
    box.setColor(touchgfx::Color::getColorFromRGB(0xc7, 0x71, 0x08));
 | 
			
		||||
  } else if (value > 0) {
 | 
			
		||||
    box.setColor(touchgfx::Color::getColorFromRGB(0xdb, 0xb2, 0x0b));
 | 
			
		||||
  } else if (value > -5) {
 | 
			
		||||
    box.setColor(touchgfx::Color::getColorFromRGB(0x80, 0xba, 0x14));
 | 
			
		||||
  } else if (value > -10) {
 | 
			
		||||
    box.setColor(touchgfx::Color::getColorFromRGB(0x09, 0x96, 0x3b));
 | 
			
		||||
  } else {
 | 
			
		||||
    box.setColor(touchgfx::Color::getColorFromRGB(0x05, 0x77, 0xa8));
 | 
			
		||||
  }
 | 
			
		||||
  box.invalidate();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ValueBuffer::ValueBuffer(touchgfx::TextAreaWithOneWildcard &field,
 | 
			
		||||
                         size_t intDigits, size_t decimalDigits)
 | 
			
		||||
    : field(field), intDigits(intDigits), decimalDigits(decimalDigits) {
 | 
			
		||||
  value.f = NAN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ValueBuffer::setField(touchgfx::TextAreaWithOneWildcard &field) {
 | 
			
		||||
  this->field = field;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ValueBuffer::setIntValue(int value) {
 | 
			
		||||
  if (value == this->value.i) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this->value.i = value;
 | 
			
		||||
 | 
			
		||||
  touchgfx::Unicode::snprintf(buffer, sizeof(buffer) / sizeof(*buffer), "%*d",
 | 
			
		||||
                              static_cast<int>(intDigits), value);
 | 
			
		||||
  field.setWildcard(buffer);
 | 
			
		||||
  field.invalidate();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ValueBuffer::setFloatValue(float value) {
 | 
			
		||||
  if (value == this->value.f) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this->value.f = value;
 | 
			
		||||
 | 
			
		||||
  size_t width = intDigits;
 | 
			
		||||
  if (decimalDigits > 0) {
 | 
			
		||||
    width += 1 + decimalDigits; // 1 for the decimal point
 | 
			
		||||
  }
 | 
			
		||||
  float params[3] = {static_cast<float>(width),
 | 
			
		||||
                     static_cast<float>(decimalDigits), value};
 | 
			
		||||
  touchgfx::Unicode::snprintfFloats(buffer, sizeof(buffer) / sizeof(*buffer),
 | 
			
		||||
                                    "%*.*f", params);
 | 
			
		||||
  field.setWildcard(buffer);
 | 
			
		||||
  field.invalidate();
 | 
			
		||||
}
 | 
			
		||||
@ -27,7 +27,7 @@ void MissionSelectPresenter::vehicleStateUpdated() {
 | 
			
		||||
    // Do nothing
 | 
			
		||||
    break;
 | 
			
		||||
  case MISSION_MANUAL:
 | 
			
		||||
    app->gotoDriverViewScreenNoTransition();
 | 
			
		||||
    app->gotoEnduranceScreenNoTransition();
 | 
			
		||||
    break;
 | 
			
		||||
  default:
 | 
			
		||||
    app->gotoAMIScreenNoTransition();
 | 
			
		||||
@ -39,7 +39,7 @@ void MissionSelectPresenter::nextScreen() {
 | 
			
		||||
      static_cast<FrontendApplication *>(FrontendApplication::getInstance());
 | 
			
		||||
  if (app->getBackToMissionSelect()) {
 | 
			
		||||
    if (vehicle_state.active_mission == MISSION_MANUAL) {
 | 
			
		||||
      app->gotoDriverViewScreenNoTransition();
 | 
			
		||||
      app->gotoEnduranceScreenNoTransition();
 | 
			
		||||
    } else {
 | 
			
		||||
      app->gotoAMIScreenNoTransition();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,56 @@
 | 
			
		||||
Model::Model() : modelListener(0) {}
 | 
			
		||||
 | 
			
		||||
#ifdef SIMULATOR
 | 
			
		||||
void Model::tick() { modelListener->vehicleStateUpdated(); }
 | 
			
		||||
void bounce(float &value, bool &rising, float step, float lower, float upper) {
 | 
			
		||||
  if (rising) {
 | 
			
		||||
    value += step;
 | 
			
		||||
    if (value > upper) {
 | 
			
		||||
      value = upper;
 | 
			
		||||
      rising = false;
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    value -= step;
 | 
			
		||||
    if (value < lower) {
 | 
			
		||||
      value = lower;
 | 
			
		||||
      rising = true;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Model::tick() {
 | 
			
		||||
  static float last_lap_delta = 0;
 | 
			
		||||
  static bool lap_delta_rising = true;
 | 
			
		||||
  static float overall_delta = 0;
 | 
			
		||||
  static bool overall_delta_rising = false;
 | 
			
		||||
  static float power_limit = 20;
 | 
			
		||||
  static bool power_limit_rising = false;
 | 
			
		||||
  static float speed_limit = 70;
 | 
			
		||||
  static bool speed_limit_rising = true;
 | 
			
		||||
  static float soc = 100;
 | 
			
		||||
  static bool soc_rising = false;
 | 
			
		||||
  static float bat_temp = 13;
 | 
			
		||||
  static bool bat_temp_rising = true;
 | 
			
		||||
 | 
			
		||||
  static int iter = 0;
 | 
			
		||||
  if (iter++ % 5 != 0) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  bounce(last_lap_delta, lap_delta_rising, 0.2, -12, 12);
 | 
			
		||||
  bounce(overall_delta, overall_delta_rising, 0.1, -12, 12);
 | 
			
		||||
  bounce(power_limit, power_limit_rising, 0.1, 5, 30);
 | 
			
		||||
  bounce(speed_limit, speed_limit_rising, 0.2, 50, 100);
 | 
			
		||||
  bounce(soc, soc_rising, 0.5, 0, 100);
 | 
			
		||||
  bounce(bat_temp, bat_temp_rising, 0.2, 10, 59);
 | 
			
		||||
  vehicle_state.bat_delta_last = last_lap_delta;
 | 
			
		||||
  vehicle_state.bat_delta_overall = overall_delta;
 | 
			
		||||
  vehicle_state.power_limit = power_limit;
 | 
			
		||||
  vehicle_state.speed_limit = speed_limit;
 | 
			
		||||
  vehicle_state.soc_ts = soc;
 | 
			
		||||
  vehicle_state.max_cell_temp = bat_temp;
 | 
			
		||||
 | 
			
		||||
  vehicle_state.active_mission = MISSION_MANUAL;
 | 
			
		||||
  modelListener->vehicleStateUpdated();
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#include "main.h"
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user