Resetting the lap counter when a new name is recived
[apps/native/gear-racing-car.git] / src / app.c
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
3  *
4  * Contact: Jeonghoon Park <jh1979.park@samsung.com>
5  *
6  * Licensed under the Flora License, Version 1.1 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://floralicense.org/license/
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an AS IS BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <math.h>
23 #include <glib.h>
24 #include <service_app.h>
25 #include "log.h"
26 #include "resource.h"
27 #include "net-util.h"
28 #include "config.h"
29 #include "cloud/cloud_communication.h"
30 #include "messages/message_manager.h"
31 #include "controller_connection_manager.h"
32 #include "lap_counter/lap_counter.h"
33 #include "command.h"
34
35 #define ENABLE_MOTOR 1
36 #define STERING_SERVO_CENTER 340
37 #define STERING_SERVO_RANGE 125
38
39 #define MAX_UDP_INPUT 10000
40
41 #define CONFIG_GRP_CAR "Car"
42 #define CONFIG_KEY_ID "Id"
43 #define CONFIG_KEY_NAME "Name"
44 #define CLOUD_REQUESTS_FREQUENCY 15
45 #define AZIMUTH_SERVO_PIN 15
46 #define ELEVATION_SERVO_PIN 14
47
48 #define ELEVATION_MIN 200
49 #define ELEVATION_MAX 400
50 #define AZIMUTH_MIN 200
51 #define AZIMUTH_MAX 700
52
53 enum {
54         DIR_STATE_S,
55         DIR_STATE_F,
56         DIR_STATE_B,
57 };
58
59 typedef struct app_data_s {
60         unsigned int f_value;
61         unsigned int r_value;
62         unsigned int dir_state;
63         const char *user_name;
64         guint idle_h;
65 } app_data;
66
67 static void _initialize_components(app_data *ad);
68 static void _initialize_config();
69
70 static void service_app_lang_changed(app_event_info_h event_info, void *user_data)
71 {
72         return;
73 }
74
75 static void service_app_region_changed(app_event_info_h event_info, void *user_data)
76 {
77         return;
78 }
79
80 static void service_app_low_battery(app_event_info_h event_info, void *user_data)
81 {
82         _E("low battery! exit app");
83         service_app_exit();
84
85         return;
86 }
87
88 static void service_app_low_memory(app_event_info_h event_info, void *user_data)
89 {
90         return;
91 }
92
93 static inline double __map_round(double val)
94 {
95         return floor(val + 0.5);
96 }
97
98 static int __map_range_val(int v_min, int v_max, int d_min, int d_max, int val)
99 {
100         int rval = 0;
101         double slope = 0;
102         slope = 1.0 * (d_max - d_min) / (v_max - v_min);
103
104         rval = d_min + __map_round(slope * (val - v_min));
105
106         return rval;
107 }
108
109 static inline int ___map_speed_val(int speed)
110 {
111         return __map_range_val(-MAX_UDP_INPUT, MAX_UDP_INPUT, -4095, 4095, speed);
112 }
113
114 static inline int ___map_servo_val(int servo)
115 {
116         return __map_range_val(-MAX_UDP_INPUT, MAX_UDP_INPUT, STERING_SERVO_CENTER - STERING_SERVO_RANGE, STERING_SERVO_CENTER + STERING_SERVO_RANGE, servo);
117 }
118
119 static int __driving_motors(int servo, int speed)
120 {
121         int val_speed;
122         int val_servo;
123
124         val_servo = ___map_servo_val(servo);
125         val_speed = ___map_speed_val(speed);
126
127         _D("control motor - servo[%4d : %4d], speed[%4d : %4d]",
128                 servo, val_servo, speed, val_speed);
129 #if ENABLE_MOTOR
130         resource_set_servo_motor_value(0, val_servo);
131         resource_set_motor_driver_L298N_speed(MOTOR_ID_1, val_speed);
132         resource_set_motor_driver_L298N_speed(MOTOR_ID_2, val_speed);
133 #endif
134
135         return 0;
136 }
137
138 static void __camera(int azimuth, int elevation)
139 {
140         int val_azimuth = __map_range_val(-MAX_UDP_INPUT, MAX_UDP_INPUT, AZIMUTH_MIN, AZIMUTH_MAX, azimuth);
141         int val_elevation = __map_range_val(0, MAX_UDP_INPUT, ELEVATION_MIN, ELEVATION_MAX, elevation); // No need to look upside down
142
143         _D("camera - azimuth[%4d : %4d], elevation[%4d : %4d]", azimuth, val_azimuth, elevation, val_elevation);
144 #if ENABLE_MOTOR
145         resource_set_servo_motor_value(ELEVATION_SERVO_PIN, val_elevation);
146         resource_set_servo_motor_value(AZIMUTH_SERVO_PIN, val_azimuth);
147 #endif
148 }
149
150 static void __command_received_cb(command_s command) {
151         switch(command.type) {
152         case COMMAND_TYPE_DRIVE:
153                 __driving_motors(command.data.steering.direction, command.data.steering.speed);
154                 break;
155         case COMMAND_TYPE_CAMERA:
156                 __camera(command.data.camera_position.camera_azimuth, command.data.camera_position.camera_elevation);
157                 break;
158         case COMMAND_TYPE_DRIVE_AND_CAMERA:
159                 __driving_motors(command.data.steering_and_camera.direction, command.data.steering_and_camera.speed);
160                 __camera(command.data.steering_and_camera.camera_azimuth, command.data.steering_and_camera.camera_elevation);
161                 break;
162         case COMMAND_TYPE_NONE:
163                 break;
164         default:
165                 _E("Unknown command type");
166                 break;
167         }
168 }
169
170 static void __user_name_received_cb(const char *name)
171 {
172         _D("User name received: %s", name);
173         lap_counter_set_user_name(name);
174         lap_counter_set_start_lap();
175 }
176
177 static void _initialize_config()
178 {
179         net_util_init();
180
181         config_init();
182
183         char *id = NULL;
184         char *name = NULL;
185         gboolean modified = false;
186         if (config_get_string(CONFIG_GRP_CAR, CONFIG_KEY_ID, &id) != 0) {
187                 char *uuid = g_uuid_string_random();
188                 config_set_string(CONFIG_GRP_CAR, CONFIG_KEY_ID, uuid);
189                 g_free(uuid);
190                 modified = true;
191         }
192         if (config_get_string(CONFIG_GRP_CAR, CONFIG_KEY_NAME, &id) != 0) {
193                 config_set_string(CONFIG_GRP_CAR, CONFIG_KEY_NAME, "Passerati");
194                 modified = true;
195         }
196         if (modified == true) {
197                 config_save();
198         }
199         free(id);
200         free(name);
201 }
202
203 static void _initialize_components(app_data *ad)
204 {
205         net_util_init();
206         _initialize_config();
207         cloud_communication_init();
208         message_manager_init();
209         controller_connection_manager_listen();
210         lap_counter_init();
211 }
212
213 static bool service_app_create(void *data)
214 {
215         int ret = 0;
216         app_data *ad = data;
217
218         _D("-----------------------=======================================================================-----------------------");
219         _D("-----------------------=======================================================================-----------------------");
220         _D("-----------------------============================== APP %s %s ==============================-----------------------", __DATE__, __TIME__);
221         _D("-----------------------=======================================================================-----------------------");
222         _D("-----------------------=======================================================================-----------------------");
223
224         /*
225          * if you want to use default configuration,
226          * Do not need to call resource_set_motor_driver_L298N_configuration(),
227          *
228         */
229 #if ENABLE_MOTOR
230         ret = resource_set_motor_driver_L298N_configuration(MOTOR_ID_1, 19, 16, 5);
231         if (ret) {
232                 _E("resource_set_motor_driver_L298N_configuration()");
233                 service_app_exit();
234         }
235         ret = resource_set_motor_driver_L298N_configuration(MOTOR_ID_2, 26, 20, 4);
236         if (ret) {
237                 _E("resource_set_motor_driver_L298N_configuration()");
238                 service_app_exit();
239         }
240 #endif
241
242         resource_lap_counter_init();
243
244         _initialize_components(ad);
245         cloud_communication_start(CLOUD_REQUESTS_FREQUENCY);
246
247         controller_connection_manager_set_command_received_cb(__command_received_cb);
248         controller_connection_manager_set_user_name_received_cb(__user_name_received_cb);
249
250         lap_counter_init();
251         return true;
252 }
253
254 static void service_app_control(app_control_h app_control, void *data)
255 {
256
257 #if ENABLE_MOTOR
258         /* set speed 0, to reduce delay of initializing motor driver */
259         resource_set_motor_driver_L298N_speed(MOTOR_ID_1, 0);
260         resource_set_motor_driver_L298N_speed(MOTOR_ID_2, 0);
261         resource_set_servo_motor_value(0, 450);
262         resource_set_servo_motor_value(ELEVATION_SERVO_PIN, ELEVATION_MIN);
263         resource_set_servo_motor_value(AZIMUTH_SERVO_PIN, (AZIMUTH_MIN + AZIMUTH_MAX) / 2);
264 #endif
265
266         return;
267 }
268
269 static void service_app_terminate(void *data)
270 {
271         app_data *ad = data;
272
273         resource_set_servo_motor_value(0, STERING_SERVO_CENTER);
274         resource_set_servo_motor_value(ELEVATION_SERVO_PIN, ELEVATION_MIN);
275         resource_set_servo_motor_value(AZIMUTH_SERVO_PIN, (AZIMUTH_MIN + AZIMUTH_MAX) / 2);
276
277         resource_lap_counter_destroy();
278
279         if (ad->idle_h)
280                 g_source_remove(ad->idle_h);
281
282         lap_counter_shutdown();
283         controller_connection_manager_release();
284         message_manager_shutdown();
285
286         cloud_communication_stop();
287         cloud_communication_fini();
288         config_shutdown();
289         net_util_fini();
290
291         resource_close_all();
292         log_file_close();
293
294         _D("Bye ~");
295
296         return;
297 }
298
299 int main(int argc, char* argv[])
300 {
301         app_data *ad = NULL;
302         int ret = 0;
303         service_app_lifecycle_callback_s event_callback;
304         app_event_handler_h handlers[5] = {NULL, };
305
306         log_type_set(LOG_TYPE_DLOG);
307
308         ad = calloc(1, sizeof(app_data));
309         retv_if(!ad, -1);
310
311         event_callback.create = service_app_create;
312         event_callback.terminate = service_app_terminate;
313         event_callback.app_control = service_app_control;
314
315         service_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY],
316                 APP_EVENT_LOW_BATTERY, service_app_low_battery, &ad);
317         service_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY],
318                 APP_EVENT_LOW_MEMORY, service_app_low_memory, &ad);
319         service_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED],
320                 APP_EVENT_LANGUAGE_CHANGED, service_app_lang_changed, &ad);
321         service_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED],
322                 APP_EVENT_REGION_FORMAT_CHANGED, service_app_region_changed, &ad);
323
324         ret = service_app_main(argc, argv, &event_callback, ad);
325         if (ret)
326                 _E("failed to start app");
327
328         return 0;
329 }