1516X Push Back 1.0
1516X's robot code for the 2025-2026 VEX Robotics Competition
Loading...
Searching...
No Matches
motorDashboard.cpp
Go to the documentation of this file.
1#include "main.h"
2#include "robodash/api.h"
3#include <vector>
4#include <algorithm>
5#include <functional>
6#include <string>
7#include "globals.h"
8
9#define TEMP_WARNING_THRESHOLD 55.0
10#define HISTORY_MAX_POINTS 25
11
13 std::string name;
14 std::function<double()> getTemp;
15 lv_obj_t* btn = nullptr;
16 lv_obj_t* label = nullptr;
17 std::vector<lv_coord_t> history;
18 bool isOverheating = false;
19
20 MotorDisplayData(std::string n, std::function<double()> f)
21 : name(n), getTemp(f) {}
22};
23
24std::vector<MotorDisplayData> motorList;
26
27lv_obj_t* modal_overlay = nullptr;
28lv_obj_t* chart_modal = nullptr;
29lv_obj_t* temp_chart = nullptr;
30lv_chart_series_t* temp_series = nullptr;
31lv_obj_t* modal_title = nullptr;
32
33static void close_modal_cb(lv_event_t * e) {
34 lv_obj_add_flag(chart_modal, LV_OBJ_FLAG_HIDDEN);
35 lv_obj_add_flag(modal_overlay, LV_OBJ_FLAG_HIDDEN);
36 activeMotor = nullptr;
37}
38
39static void motor_click_cb(lv_event_t * e) {
40 MotorDisplayData* md = (MotorDisplayData*)lv_event_get_user_data(e);
41 activeMotor = md;
42
43 lv_label_set_text(modal_title, md->name.c_str());
44
45 lv_coord_t latest = md->history.empty() ? 20 : md->history.back();
46
47 if (latest >= TEMP_WARNING_THRESHOLD) {
48 lv_chart_set_series_color(temp_chart, temp_series, lv_color_hex(0xFF4A4A));
49 } else {
50 lv_chart_set_series_color(temp_chart, temp_series, lv_color_hex(0x4CAF50));
51 }
52
53 lv_chart_set_ext_y_array(temp_chart, temp_series, md->history.data());
54 lv_chart_refresh(temp_chart);
55
56 lv_obj_move_foreground(modal_overlay);
57 lv_obj_move_foreground(chart_modal);
58
59 lv_obj_clear_flag(modal_overlay, LV_OBJ_FLAG_HIDDEN);
60 lv_obj_clear_flag(chart_modal, LV_OBJ_FLAG_HIDDEN);
61}
62
63static void update_temps_cb(lv_timer_t * timer) {
64 for(auto& md : motorList) {
65 double rawTemp = md.getTemp();
66 lv_coord_t currentTemp = (lv_coord_t)rawTemp;
67
68 std::rotate(md.history.begin(), md.history.begin() + 1, md.history.end());
69 md.history.back() = currentTemp;
70
71 char buf[32];
72 snprintf(buf, sizeof(buf), "%s\n%d°C", md.name.c_str(), currentTemp);
73 lv_label_set_text(md.label, buf);
74
75 bool nowOverheating = (rawTemp >= TEMP_WARNING_THRESHOLD);
76 if (nowOverheating != md.isOverheating) {
77 md.isOverheating = nowOverheating;
78 if (nowOverheating) {
79 lv_obj_set_style_bg_color(md.btn, lv_color_hex(0xD32F2F), 0);
80 } else {
81 lv_obj_set_style_bg_color(md.btn, lv_color_hex(0x2A3D8F), 0);
82 }
83 }
84
85 if (!lv_obj_has_flag(chart_modal, LV_OBJ_FLAG_HIDDEN) && activeMotor == &md) {
86 if (currentTemp >= TEMP_WARNING_THRESHOLD) {
87 lv_chart_set_series_color(temp_chart, temp_series, lv_color_hex(0xFF4A4A));
88 } else {
89 lv_chart_set_series_color(temp_chart, temp_series, lv_color_hex(0x4CAF50));
90 }
91
92 lv_chart_refresh(temp_chart);
93 }
94 }
95}
96
98 rd_view_t* motor_view = rd_view_create("Motors");
99
100 lv_obj_t* parent = rd_view_obj(motor_view);
101 lv_obj_set_style_bg_color(parent, lv_color_hex(0x1E1E1E), 0);
102
103 lv_obj_t* btn_container = lv_obj_create(parent);
104 lv_obj_set_size(btn_container, LV_PCT(100), LV_PCT(100));
105 lv_obj_set_style_bg_opa(btn_container, 0, 0);
106 lv_obj_set_style_border_width(btn_container, 0, 0);
107
108 lv_obj_set_layout(btn_container, LV_LAYOUT_FLEX);
109 lv_obj_set_flex_flow(btn_container, LV_FLEX_FLOW_ROW_WRAP);
110 lv_obj_set_flex_align(btn_container, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
111
112 motorList = {
113 MotorDisplayData("Right Drive\n", [](){ return rightMotors.get_temperature(); }),
114 MotorDisplayData("Left Drive\n", [](){ return leftMotors.get_temperature(); }),
115 MotorDisplayData("Intake\n", [](){ return intakeMotor.get_temperature(); }),
116 MotorDisplayData("Outtake\n", [](){ return outtakeMotor.get_temperature(); }),
117 MotorDisplayData("Storage\n", [](){ return storageMotor.get_temperature(); })
118 };
119
120 for(auto& md : motorList) {
121 md.history.assign(HISTORY_MAX_POINTS, 20);
122
123 md.btn = lv_btn_create(btn_container);
124 lv_obj_set_size(md.btn, 100, 100);
125 lv_obj_set_style_radius(md.btn, 8, 0);
126 lv_obj_set_style_bg_color(md.btn, lv_color_hex(0x2A3D8F), 0);
127 lv_obj_set_style_shadow_width(md.btn, 0, 0);
128 lv_obj_clear_flag(md.btn, LV_OBJ_FLAG_SCROLLABLE);
129 lv_obj_add_event_cb(md.btn, motor_click_cb, LV_EVENT_CLICKED, &md);
130
131 md.label = lv_label_create(md.btn);
132 lv_label_set_text(md.label, md.name.c_str());
133 lv_obj_align(md.label, LV_ALIGN_TOP_MID, 0, 15);
134 lv_obj_set_style_text_align(md.label, LV_TEXT_ALIGN_CENTER, 0);
135 lv_obj_set_style_text_color(md.label, lv_color_hex(0xFFFFFF), 0);
136
137 lv_obj_t* vent = lv_obj_create(md.btn);
138 lv_obj_set_size(vent, 50, 25);
139 lv_obj_align(vent, LV_ALIGN_BOTTOM_MID, 0, -12);
140 lv_obj_set_style_bg_color(vent, lv_color_hex(0x111111), 0);
141 lv_obj_set_style_bg_opa(vent, 100, 0);
142 lv_obj_set_style_border_width(vent, 1, 0);
143 lv_obj_set_style_border_color(vent, lv_color_hex(0x000000), 0);
144 lv_obj_clear_flag(vent, LV_OBJ_FLAG_CLICKABLE);
145 lv_obj_clear_flag(vent, LV_OBJ_FLAG_SCROLLABLE);
146 }
147
148 modal_overlay = lv_obj_create(parent);
149 lv_obj_set_size(modal_overlay, LV_PCT(100), LV_PCT(100));
150 lv_obj_set_style_bg_color(modal_overlay, lv_color_hex(0x000000), 0);
151 lv_obj_set_style_bg_opa(modal_overlay, LV_OPA_50, 0);
152 lv_obj_set_style_border_width(modal_overlay, 0, 0);
153 lv_obj_add_flag(modal_overlay, LV_OBJ_FLAG_HIDDEN);
154 lv_obj_add_flag(modal_overlay, LV_OBJ_FLAG_CLICKABLE);
155
156 chart_modal = lv_obj_create(parent);
157 lv_obj_set_size(chart_modal, 400, 200);
158 lv_obj_center(chart_modal);
159 lv_obj_set_style_bg_color(chart_modal, lv_color_hex(0x222222), 0);
160 lv_obj_set_style_border_color(chart_modal, lv_color_hex(0x555555), 0);
161 lv_obj_set_style_border_width(chart_modal, 2, 0);
162 lv_obj_add_flag(chart_modal, LV_OBJ_FLAG_HIDDEN);
163
164 modal_title = lv_label_create(chart_modal);
165 lv_label_set_text(modal_title, "Motor Name");
166 lv_obj_align(modal_title, LV_ALIGN_TOP_MID, 0, 0);
167 lv_obj_set_style_text_color(modal_title, lv_color_hex(0xFFFFFF), 0);
168
169 lv_obj_t* close_btn = lv_btn_create(chart_modal);
170 lv_obj_set_size(close_btn, 60, 30);
171 lv_obj_align(close_btn, LV_ALIGN_TOP_RIGHT, 0, -10);
172 lv_obj_t* close_lbl = lv_label_create(close_btn);
173 lv_label_set_text(close_lbl, "Close");
174 lv_obj_center(close_lbl);
175 lv_obj_add_event_cb(close_btn, close_modal_cb, LV_EVENT_CLICKED, NULL);
176
177 temp_chart = lv_chart_create(chart_modal);
178 lv_obj_set_size(temp_chart, 330, 145);
179 lv_obj_align(temp_chart, LV_ALIGN_BOTTOM_MID, 0, 0);
180 lv_chart_set_type(temp_chart, LV_CHART_TYPE_LINE);
181
182 lv_chart_set_range(temp_chart, LV_CHART_AXIS_PRIMARY_Y, 10, 60);
183 lv_chart_set_axis_tick(temp_chart, LV_CHART_AXIS_PRIMARY_Y, 10, 5, 8, 1, true, 40);
184
185 lv_chart_set_point_count(temp_chart, HISTORY_MAX_POINTS);
186 temp_series = lv_chart_add_series(temp_chart, lv_color_hex(0x4CAF50), LV_CHART_AXIS_PRIMARY_Y);
187
188 lv_timer_create(update_temps_cb, 10000, NULL);
189}
pros::Motor storageMotor(2, pros::v5::MotorGears::blue)
pros::Motor outtakeMotor(3, pros::MotorGears::blue)
lemlib::Drivetrain drivebase & leftMotors
Definition globals.cpp:17
pros::Motor intakeMotor(-1, pros::v5::MotorGears::blue)
pros::MotorGroup rightMotors({17, 19, -18}, pros::MotorGears::blue)
static void close_modal_cb(lv_event_t *e)
#define HISTORY_MAX_POINTS
lv_obj_t * modal_title
MotorDisplayData * activeMotor
lv_obj_t * temp_chart
static void motor_click_cb(lv_event_t *e)
lv_chart_series_t * temp_series
std::vector< MotorDisplayData > motorList
void init_motor_dashboard()
lv_obj_t * chart_modal
lv_obj_t * modal_overlay
#define TEMP_WARNING_THRESHOLD
static void update_temps_cb(lv_timer_t *timer)
std::vector< lv_coord_t > history
std::function< double()> getTemp
MotorDisplayData(std::string n, std::function< double()> f)