1
+ /* *************************************************************************************
2
+ * INCLUDE
3
+ **************************************************************************************/
4
+
5
+ #include " AppState.h"
6
+
7
+ /* *************************************************************************************
8
+ * DEFINE
9
+ **************************************************************************************/
10
+
11
+ #define COLOR_TEAL 0x00878F
12
+ #define COLOR_LIGHT_TEAL 0x62AEB2
13
+ #define COLOR_ORANGE 0xE47128
14
+
15
+ #define BUTTON_ENTER 6
16
+
17
+ /* *************************************************************************************
18
+ * CONSTANT
19
+ **************************************************************************************/
20
+
21
+ static int const SAMPLE_BUF_SIZE = 6 *200 *2 ; /* 20 seconds. */
22
+ static float const HOME_POS[6 ] = {157.5 , 157.5 , 157.5 , 157.5 , 157.5 , 90.0 };
23
+
24
+ /* *************************************************************************************
25
+ * GLOBAL VARIABLES
26
+ **************************************************************************************/
27
+
28
+ lv_obj_t * counter;
29
+ lv_obj_t * btnm;
30
+ const char * btnm_map[] = { " RECORD" , " \n " , " REPLAY" , " \n " , " ZERO_POSITION" , " \n " , " \0 " };
31
+
32
+ static float sample_buf[SAMPLE_BUF_SIZE];
33
+ static int sample_cnt;
34
+
35
+ extern LearnAndRepeatApp app;
36
+
37
+ /* *************************************************************************************
38
+ * FUNCTION DEFINITION
39
+ **************************************************************************************/
40
+
41
+ static void event_handler_menu (lv_event_t * e)
42
+ {
43
+ lv_event_code_t code = lv_event_get_code (e);
44
+
45
+ if (code == LV_EVENT_CLICKED || (code == LV_EVENT_KEY && Braccio.getKey () == BUTTON_ENTER))
46
+ {
47
+ lv_obj_t * obj = lv_event_get_target (e);
48
+ uint32_t const id = lv_btnmatrix_get_selected_btn (obj);
49
+
50
+ switch (id)
51
+ {
52
+ case 0 : app.update (EventSource::Button_Record); break ;
53
+ case 1 : app.update (EventSource::Button_Replay); break ;
54
+ case 2 : app.update (EventSource::Button_ZeroPosition); break ;
55
+ }
56
+ }
57
+ }
58
+
59
+ void custom_main_menu ()
60
+ {
61
+ Braccio.lvgl_lock ();
62
+ static lv_style_t style_focus;
63
+ lv_style_init (&style_focus);
64
+ lv_style_set_outline_color (&style_focus, lv_color_hex (COLOR_ORANGE));
65
+ lv_style_set_outline_width (&style_focus, 4 );
66
+
67
+ static lv_style_t style_btn;
68
+ lv_style_init (&style_btn);
69
+ lv_style_set_bg_color (&style_btn, lv_color_hex (COLOR_LIGHT_TEAL));
70
+ lv_style_set_text_color (&style_btn, lv_color_white ());
71
+
72
+ btnm = lv_btnmatrix_create (lv_scr_act ());
73
+ lv_obj_set_size (btnm, 240 , 240 );
74
+ lv_btnmatrix_set_map (btnm, btnm_map);
75
+ lv_obj_align (btnm, LV_ALIGN_CENTER, 0 , 0 );
76
+
77
+ lv_obj_add_style (btnm, &style_btn, LV_PART_ITEMS);
78
+ lv_obj_add_style (btnm, &style_focus, LV_PART_ITEMS | LV_STATE_FOCUS_KEY);
79
+
80
+ lv_btnmatrix_set_btn_ctrl (btnm, 0 , LV_BTNMATRIX_CTRL_DISABLED);
81
+ lv_btnmatrix_set_btn_ctrl (btnm, 1 , LV_BTNMATRIX_CTRL_DISABLED);
82
+ lv_btnmatrix_set_btn_ctrl (btnm, 2 , LV_BTNMATRIX_CTRL_DISABLED);
83
+
84
+ lv_btnmatrix_set_one_checked (btnm, true );
85
+ lv_btnmatrix_set_selected_btn (btnm, 0 );
86
+ lv_btnmatrix_set_btn_ctrl (btnm, 2 , LV_BTNMATRIX_CTRL_CHECKED);
87
+
88
+ counter = lv_label_create (btnm);
89
+ lv_label_set_text_fmt (counter, " Counter: %d" , 0 );
90
+ lv_obj_align (counter, LV_ALIGN_CENTER, 0 , 80 );
91
+
92
+ lv_obj_add_event_cb (btnm, event_handler_menu, LV_EVENT_ALL, NULL );
93
+ Braccio.lvgl_unlock ();
94
+
95
+ Braccio.connectJoystickTo (btnm);
96
+ }
97
+
98
+ /* *************************************************************************************
99
+ * State
100
+ **************************************************************************************/
101
+
102
+ State * State::handle_OnZeroPosition ()
103
+ {
104
+ return new ZeroState ();
105
+ }
106
+
107
+ /* *************************************************************************************
108
+ * IdleState
109
+ **************************************************************************************/
110
+
111
+ void IdleState::onEnter ()
112
+ {
113
+ lv_btnmatrix_set_btn_ctrl (btnm, 2 , LV_BTNMATRIX_CTRL_CHECKED);
114
+ }
115
+
116
+ void IdleState::onExit ()
117
+ {
118
+ lv_btnmatrix_clear_btn_ctrl (btnm, 2 , LV_BTNMATRIX_CTRL_CHECKED);
119
+ }
120
+
121
+ State * IdleState::handle_OnRecord ()
122
+ {
123
+ return new RecordState ();
124
+ }
125
+
126
+ State * IdleState::handle_OnReplay ()
127
+ {
128
+ return new ReplayState ();
129
+ }
130
+
131
+ /* *************************************************************************************
132
+ * RecordState
133
+ **************************************************************************************/
134
+
135
+ void RecordState::onEnter ()
136
+ {
137
+ btnm_map[0 ] = " STOP" ;
138
+ lv_btnmatrix_set_btn_ctrl (btnm, 0 , LV_BTNMATRIX_CTRL_CHECKED);
139
+ lv_btnmatrix_set_btn_ctrl (btnm, 1 , LV_BTNMATRIX_CTRL_DISABLED);
140
+
141
+ Braccio.disengage ();
142
+ sample_cnt = 0 ;
143
+ }
144
+
145
+ void RecordState::onExit ()
146
+ {
147
+ btnm_map[0 ] = " RECORD" ;
148
+ lv_btnmatrix_clear_btn_ctrl (btnm, 0 , LV_BTNMATRIX_CTRL_CHECKED);
149
+ lv_btnmatrix_clear_btn_ctrl (btnm, 1 , LV_BTNMATRIX_CTRL_DISABLED);
150
+ lv_label_set_text_fmt (counter, " Counter: %d" , 0 );
151
+
152
+ Braccio.engage ();
153
+ }
154
+
155
+ State * RecordState::handle_OnRecord ()
156
+ {
157
+ return new IdleState ();
158
+ }
159
+
160
+ State * RecordState::handle_OnTimerTick ()
161
+ {
162
+ /* The sample buffer is full. */
163
+ if (sample_cnt >= SAMPLE_BUF_SIZE) {
164
+ return new IdleState ();
165
+ }
166
+
167
+ /* We still have space, let's sample some data. */
168
+ Braccio.positions (sample_buf + sample_cnt);
169
+ sample_cnt += 6 ;
170
+
171
+ /* Update sample counter. */
172
+ lv_label_set_text_fmt (counter, " Counter: %d" , (sample_cnt / 6 ));
173
+
174
+ return this ;
175
+ }
176
+
177
+ /* *************************************************************************************
178
+ * ReplayState
179
+ **************************************************************************************/
180
+
181
+ void ReplayState::onEnter ()
182
+ {
183
+ btnm_map[2 ] = " STOP" ;
184
+ lv_btnmatrix_set_btn_ctrl (btnm, 0 , LV_BTNMATRIX_CTRL_DISABLED);
185
+ lv_btnmatrix_set_btn_ctrl (btnm, 1 , LV_BTNMATRIX_CTRL_CHECKED);
186
+ }
187
+
188
+ void ReplayState::onExit ()
189
+ {
190
+ btnm_map[2 ] = " REPLAY" ;
191
+ lv_btnmatrix_clear_btn_ctrl (btnm, 0 , LV_BTNMATRIX_CTRL_DISABLED);
192
+ lv_btnmatrix_clear_btn_ctrl (btnm, 1 , LV_BTNMATRIX_CTRL_CHECKED);
193
+ lv_label_set_text_fmt (counter, " Counter: %d" , 0 );
194
+ }
195
+
196
+ State * ReplayState::handle_OnReplay ()
197
+ {
198
+ return new IdleState ();
199
+ }
200
+
201
+ State * ReplayState::handle_OnTimerTick ()
202
+ {
203
+ /* All samples have been replayed. */
204
+ if (_replay_cnt >= sample_cnt) {
205
+ return new IdleState ();
206
+ }
207
+
208
+ /* Replay recorded movements. */
209
+ Braccio.moveTo (sample_buf[_replay_cnt + 0 ],
210
+ sample_buf[_replay_cnt + 1 ],
211
+ sample_buf[_replay_cnt + 2 ],
212
+ sample_buf[_replay_cnt + 3 ],
213
+ sample_buf[_replay_cnt + 4 ],
214
+ sample_buf[_replay_cnt + 5 ]);
215
+ _replay_cnt += 6 ;
216
+
217
+ lv_label_set_text_fmt (counter, " Counter: %d" , (_replay_cnt / 6 ));
218
+
219
+ return this ;
220
+ }
221
+
222
+ /* *************************************************************************************
223
+ * ReplayState
224
+ **************************************************************************************/
225
+
226
+ State * ZeroState::handle_OnTimerTick ()
227
+ {
228
+ return new IdleState ();
229
+ }
230
+
231
+ void ZeroState::onEnter ()
232
+ {
233
+ lv_btnmatrix_set_btn_ctrl (btnm, 1 , LV_BTNMATRIX_CTRL_DISABLED);
234
+ lv_btnmatrix_set_btn_ctrl (btnm, 2 , LV_BTNMATRIX_CTRL_CHECKED);
235
+
236
+ Braccio.engage ();
237
+ delay (100 );
238
+ Braccio.moveTo (HOME_POS[0 ], HOME_POS[1 ], HOME_POS[2 ], HOME_POS[3 ], HOME_POS[4 ], HOME_POS[5 ]);
239
+ delay (500 );
240
+ }
241
+
242
+ void ZeroState::onExit ()
243
+ {
244
+ lv_btnmatrix_clear_btn_ctrl (btnm, 2 , LV_BTNMATRIX_CTRL_CHECKED);
245
+ }
246
+
247
+ /* *************************************************************************************
248
+ * LearnAndRepeatApp
249
+ **************************************************************************************/
250
+
251
+ void LearnAndRepeatApp::enableButtons ()
252
+ {
253
+ /* Enable buttons once init is complete. */
254
+ lv_btnmatrix_clear_btn_ctrl (btnm, 0 , LV_BTNMATRIX_CTRL_DISABLED);
255
+ lv_btnmatrix_clear_btn_ctrl (btnm, 2 , LV_BTNMATRIX_CTRL_DISABLED);
256
+ }
0 commit comments