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