Code fixes. Some logs added
[apps/native/gear-racing-car.git] / src / app.c
index fa9977a..0330a21 100644 (file)
--- a/src/app.c
+++ b/src/app.c
 #include <service_app.h>
 #include "log.h"
 #include "resource.h"
-#include "receiver.h"
-#include "message.h"
-#include "connection_manager.h"
 #include "net-util.h"
+#include "config.h"
+#include "cloud/cloud_communication.h"
+#include "messages/message_manager.h"
+#include "controller_connection_manager.h"
+#include "lap_counter/lap_counter.h"
+#include "command.h"
 
 #define ENABLE_MOTOR 1
+#define STERING_SERVO_CENTER 340
+#define STERING_SERVO_RANGE 125
+
+#define MAX_UDP_INPUT 10000
+
+#define CONFIG_GRP_CAR "Car"
+#define CONFIG_GRP_STEERING "Steering"
+#define CONFIG_GRP_CAMERA "Camera"
+#define CONFIG_GRP_ENGINE "Engine"
+#define CONFIG_GRP_RPI "Rpi"
+
+#define CONFIG_KEY_ID "Id"
+#define CONFIG_KEY_NAME "Name"
+
+#define CONFIG_KEY_STEERING_CENTER "Center"
+#define CONFIG_KEY_STEERING_RANGE "Range"
+#define CONFIG_KEY_CAMERA_AZIMUTH_CENTER "Azimuth.Center"
+#define CONFIG_KEY_CAMERA_AZIMUTH_RANGE "Azimuth.Range"
+#define CONFIG_KEY_CAMERA_ELEVATION_MIN "Elevation.Min"
+#define CONFIG_KEY_CAMERA_ELEVATION_MAX "Elevation.Max"
+#define CONFIG_KEY_CAMERA_ENGINE_MIN "Min"
+#define CONFIG_KEY_CAMERA_ENGINE_MAX "Max"
+
+#define CONFIG_KEY_RPI_PIN_STERING "Stering"
+#define CONFIG_KEY_RPI_PIN_CAMERA_AZIMUTH "Azimuth"
+#define CONFIG_KEY_RPI_PIN_CAMERA_ELEVATION "Elevation"
+
+#define CONFIG_KEY_RPI_PIN_ENGINE_1_FORWARD "1.forward"
+#define CONFIG_KEY_RPI_PIN_ENGINE_1_BACK "1.back"
+#define CONFIG_KEY_RPI_ENGINE_CHANNEL_1 "Channel.1"
+#define CONFIG_KEY_RPI_PIN_ENGINE_2_FORWARD "2.forward"
+#define CONFIG_KEY_RPI_PIN_ENGINE_2_BACK "2.back"
+#define CONFIG_KEY_RPI_ENGINE_CHANNEL_2 "Channel.2"
+
+#define CLOUD_REQUESTS_FREQUENCY 15
+
+#define ELEVATION_MIN 200
+#define ELEVATION_MAX 400
+#define AZIMUTH_MIN 200
+#define AZIMUTH_MAX 700
+
+#define CONFIG_LED_STATE_KEY_INIT "init"
+#define CONFIG_DEFAULT_LED_3BIT_INIT 1, 1, 0
+#define CONFIG_DEFAULT_LED_24BIT_INIT 255, 32, 0
+
+#define CONFIG_LED_STATE_KEY_OFF "off"
+#define CONFIG_DEFAULT_LED_3BIT_OFF 0, 0, 0
+#define CONFIG_DEFAULT_LED_24BIT_OFF 0, 0, 0
 
 enum {
        DIR_STATE_S,
@@ -41,9 +92,65 @@ typedef struct app_data_s {
        unsigned int f_value;
        unsigned int r_value;
        unsigned int dir_state;
+       const char *user_name;
        guint idle_h;
+
+       int stering_center;
+       int stering_range;
+
+       int camera_azimuth_center;
+       int camera_azimuth_range;
+
+       int camera_elevation_min;
+       int camera_elevation_max;
+
+       int engine_min;
+       int engine_max;
+
+       int stering_pin;
+
+       int elevation_pin;
+       int azimuth_pin;
+
+       int engine_1_forward_pin;
+       int engine_1_back_pin;
+       int engine_1_channel;
+
+       int engine_2_forward_pin;
+       int engine_2_back_pin;
+       int engine_2_channel;
 } app_data;
 
+static app_data s_info = {
+               .stering_center = STERING_SERVO_CENTER,
+               .stering_range = STERING_SERVO_RANGE,
+
+               .camera_azimuth_center = (AZIMUTH_MAX + AZIMUTH_MIN) /2,
+               .camera_azimuth_range = AZIMUTH_MAX - ((AZIMUTH_MAX + AZIMUTH_MIN) /2),
+
+               .camera_elevation_min = ELEVATION_MIN,
+               .camera_elevation_max = ELEVATION_MAX,
+
+               .engine_min = -4095,
+               .engine_max = 4095,
+
+               .stering_pin = 0,
+
+               .elevation_pin = 14,
+               .azimuth_pin = 15,
+
+               .engine_1_forward_pin = 6,
+               .engine_1_back_pin = 5,
+               .engine_1_channel = 5,
+
+               .engine_2_forward_pin = 21,
+               .engine_2_back_pin = 20,
+               .engine_2_channel = 4,
+};
+
+static void _initialize_components(app_data *ad);
+static void _initialize_config();
+
 static void service_app_lang_changed(app_event_info_h event_info, void *user_data)
 {
        return;
@@ -72,7 +179,7 @@ static inline double __map_round(double val)
        return floor(val + 0.5);
 }
 
-static int __map_range_val(int d_max, int d_min, int v_max, int v_min, int val)
+static int __map_range_val(int v_min, int v_max, int d_min, int d_max, int val)
 {
        int rval = 0;
        double slope = 0;
@@ -83,29 +190,18 @@ static int __map_range_val(int d_max, int d_min, int v_max, int v_min, int val)
        return rval;
 }
 
-static int ___map_speed_val(int speed)
+static inline int ___map_speed_val(int speed)
 {
-       static const int motor_max = 4095;
-       static const int motor_min = -4095;
-       static const int speed_max = 1000;
-       static const int speed_min = -1000;
-
-       return __map_range_val(motor_max, motor_min,
-               speed_max, speed_min, speed);
+       return __map_range_val(-MAX_UDP_INPUT, MAX_UDP_INPUT, s_info.engine_min, s_info.engine_max, speed);
 }
 
-static int ___map_servo_val(int servo)
+static inline int ___map_servo_val(int servo)
 {
-       static const int motor_max = 500;
-       static const int motor_min = 400;
-       static const int servo_max = 1000;
-       static const int servo_min = -1000;
-
-       return __map_range_val(motor_max, motor_min,
-               servo_max, servo_min, servo);
+       return __map_range_val(-MAX_UDP_INPUT, MAX_UDP_INPUT,
+                       s_info.stering_center - s_info.stering_range,
+                       s_info.stering_center + s_info.stering_range, servo);
 }
 
-
 static int __driving_motors(int servo, int speed)
 {
        int val_speed;
@@ -125,139 +221,220 @@ static int __driving_motors(int servo, int speed)
        return 0;
 }
 
-static gboolean __message_dispatcher(gpointer user_data)
+static void __camera(int azimuth, int elevation)
 {
-       message_s *msg = NULL;
-
-       do {
-               msg = message_pop_from_inqueue();
-               if (msg) {
-                       switch (msg->cmd) {
-                       case MESSAGE_CMD_HELLO:
-                               /* TODO : say hello to sender */
-                               break;
-                       case MESSAGE_CMD_CALIBRATION:
-                               /* TODO : set calibration mode */
-                               break;
-                       case MESSAGE_CMD_DRIVE:
-                               /* TODO : driving car */
-                               __driving_motors(msg->servo, msg->speed);
-                               break;
-                       case MESSAGE_CMD_BYE:
-                               __driving_motors(0, 0);
-                               break;
-                       }
-               }
-               free(msg);
-       } while (msg);
-
-       return TRUE;
+       int val_azimuth = __map_range_val(-MAX_UDP_INPUT, MAX_UDP_INPUT,
+                       s_info.camera_azimuth_center - s_info.camera_azimuth_range,
+                       s_info.camera_azimuth_center + s_info.camera_azimuth_range, azimuth);
+
+       int val_elevation = __map_range_val(0, MAX_UDP_INPUT, s_info.camera_elevation_min, s_info.camera_elevation_max, elevation); // No need to look upside down
+
+       _D("camera - azimuth[%4d : %4d], elevation[%4d : %4d]", azimuth, val_azimuth, elevation, val_elevation);
+#if ENABLE_MOTOR
+       resource_set_servo_motor_value(s_info.elevation_pin, val_elevation);
+       resource_set_servo_motor_value(s_info.azimuth_pin, val_azimuth);
+#endif
 }
 
-static void __recv_state_change(receiver_type_e type,
-       receiver_state_e state, void* user_data)
-{
-       app_data *ad = user_data;
-       ret_if(!ad);
-
-       _D("receiver type[%d] state changed[%d]", type, state);
-
-       if (state == RECEIVER_STATE_CONNECTED) {
-               if (!ad->idle_h)
-                       ad->idle_h = g_idle_add(__message_dispatcher, ad);
-       } else {
-               if (ad->idle_h) {
-                       g_source_remove(ad->idle_h);
-                       ad->idle_h = 0;
-               }
-               __driving_motors(0, 0);
+static void __command_received_cb(command_s command) {
+       switch(command.type) {
+       case COMMAND_TYPE_DRIVE:
+               __driving_motors(command.data.steering.direction, command.data.steering.speed);
+               break;
+       case COMMAND_TYPE_CAMERA:
+               __camera(command.data.camera_position.camera_azimuth, command.data.camera_position.camera_elevation);
+               break;
+       case COMMAND_TYPE_DRIVE_AND_CAMERA:
+               __driving_motors(command.data.steering_and_camera.direction, command.data.steering_and_camera.speed);
+               __camera(command.data.steering_and_camera.camera_azimuth, command.data.steering_and_camera.camera_elevation);
+               break;
+       case COMMAND_TYPE_NONE:
+               break;
+       default:
+               _E("Unknown command type");
+               break;
        }
+}
 
-       return;
+static void __user_name_received_cb(const char *name)
+{
+       _D("User name received: %s", name);
+       lap_counter_set_user_name(name);
+       lap_counter_set_start_lap();
 }
 
-static void __conn_state_changed_cb(connection_state_e state,
-       const char *ip, void* user_data)
+static void _initialize_config()
 {
-       app_data *ad = user_data;
+       net_util_init();
 
-       _D("connection state changed : %d", state);
+       config_init();
+
+       char *id = NULL;
+       char *name = NULL;
+       gboolean modified = false;
+
+       if (config_get_string(CONFIG_GRP_CAR, CONFIG_KEY_ID, &id) != 0) {
+               char *uuid = g_uuid_string_random();
+               config_set_string(CONFIG_GRP_CAR, CONFIG_KEY_ID, uuid);
+               g_free(uuid);
+               modified = true;
+       }
 
-       if (state == CONNECTION_STATE_CONNECTED) {
-               receiver_start(RECEIVER_TYPE_UDP);
+       char *uuid = g_uuid_string_random();
+       modified |= config_get_string_or_set_default(CONFIG_GRP_CAR, CONFIG_KEY_ID, uuid, &id);
+       g_free(uuid);
 
-       } else {
-               receiver_stop(RECEIVER_TYPE_UDP);
+       modified |= config_get_string_or_set_default(CONFIG_GRP_CAR, CONFIG_KEY_NAME, "Pink Car", &name);
 
-               if (ad->idle_h) {
-                       g_source_remove(ad->idle_h);
-                       ad->idle_h = 0;
-               }
+       modified |= config_get_int_with_default(CONFIG_GRP_STEERING, CONFIG_KEY_STEERING_CENTER, s_info.stering_center, &s_info.stering_center);
+       modified |= config_get_int_with_default(CONFIG_GRP_STEERING, CONFIG_KEY_STEERING_RANGE, s_info.stering_range, &s_info.stering_range);
 
-               __driving_motors(0, 0);
+       modified |= config_get_int_with_default(CONFIG_GRP_CAMERA, CONFIG_KEY_CAMERA_AZIMUTH_CENTER, s_info.camera_azimuth_center, &s_info.camera_azimuth_center);
+       modified |= config_get_int_with_default(CONFIG_GRP_CAMERA, CONFIG_KEY_CAMERA_AZIMUTH_RANGE, s_info.camera_azimuth_range, &s_info.camera_azimuth_range);
+       modified |= config_get_int_with_default(CONFIG_GRP_CAMERA, CONFIG_KEY_CAMERA_ELEVATION_MIN, s_info.camera_elevation_min, &s_info.camera_elevation_min);
+       modified |= config_get_int_with_default(CONFIG_GRP_CAMERA, CONFIG_KEY_CAMERA_ELEVATION_MAX, s_info.camera_elevation_max, &s_info.camera_elevation_max);
+
+       modified |= config_get_int_with_default(CONFIG_GRP_ENGINE, CONFIG_KEY_CAMERA_ENGINE_MIN, s_info.engine_min, &s_info.engine_min);
+       modified |= config_get_int_with_default(CONFIG_GRP_ENGINE, CONFIG_KEY_CAMERA_ENGINE_MAX, s_info.engine_max, &s_info.engine_max);
+
+       modified |= config_get_int_with_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_PIN_STERING, s_info.stering_pin, &s_info.stering_pin);
+       modified |= config_get_int_with_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_PIN_CAMERA_AZIMUTH, s_info.azimuth_pin, &s_info.azimuth_pin);
+       modified |= config_get_int_with_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_PIN_CAMERA_ELEVATION, s_info.elevation_pin, &s_info.elevation_pin);
+
+       modified |= config_get_int_with_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_PIN_ENGINE_1_FORWARD, s_info.engine_1_forward_pin, &s_info.engine_1_forward_pin);
+       modified |= config_get_int_with_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_PIN_ENGINE_1_BACK, s_info.engine_1_back_pin, &s_info.engine_1_back_pin);
+       modified |= config_get_int_with_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_ENGINE_CHANNEL_1, s_info.engine_1_channel, &s_info.engine_1_channel);
+
+       modified |= config_get_int_with_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_PIN_ENGINE_2_FORWARD, s_info.engine_2_forward_pin, &s_info.engine_2_forward_pin);
+       modified |= config_get_int_with_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_PIN_ENGINE_2_BACK, s_info.engine_2_back_pin, &s_info.engine_2_back_pin);
+       modified |= config_get_int_with_default(CONFIG_GRP_RPI, CONFIG_KEY_RPI_ENGINE_CHANNEL_2, s_info.engine_2_channel, &s_info.engine_2_channel);
+
+       if (modified == true) {
+               config_save();
        }
-       return;
+
+       free(id);
+       free(name);
+}
+
+static void _initialize_components(app_data *ad)
+{
+       FUNCTION_START;
+
+       net_util_init();
+       _initialize_config();
+       cloud_communication_init();
+       message_manager_init();
+       controller_connection_manager_listen();
+       lap_counter_init();
+       resource_led_init();
+
+
+       _D("Car settings: Stering[%d +/- %d] Engine[%d - %d], CamAzimuth[%d +/- %d], CamElev[%d - %d]",
+                       s_info.stering_center, s_info.stering_range,
+                       s_info.engine_min, s_info.engine_max,
+                       s_info.camera_azimuth_center, s_info.camera_azimuth_range,
+                       s_info.camera_elevation_min, s_info.camera_elevation_max);
+
+       _D("RPI: Stering[%d], Azimuth[%d], Elev[%d]; ENG_1[%d, %d, %d]; ENG_2[%d, %d, %d];",
+                       s_info.stering_pin, s_info.azimuth_pin, s_info.elevation_pin,
+                       s_info.engine_1_forward_pin, s_info.engine_1_back_pin, s_info.engine_1_channel,
+                       s_info.engine_2_forward_pin, s_info.engine_2_back_pin, s_info.engine_2_channel);
+
+       FUNCTION_END;
 }
 
 static bool service_app_create(void *data)
 {
+       FUNCTION_START;
+
        int ret = 0;
        app_data *ad = data;
 
+       _D("-----------------------=======================================================================-----------------------");
+       _D("-----------------------=======================================================================-----------------------");
+       _D("-----------------------============================== APP %s %s ==============================-----------------------", __DATE__, __TIME__);
+       _D("-----------------------=======================================================================-----------------------");
+       _D("-----------------------=======================================================================-----------------------");
+
+       _initialize_components(ad);
+
        /*
         * if you want to use default configuration,
         * Do not need to call resource_set_motor_driver_L298N_configuration(),
         *
        */
 #if ENABLE_MOTOR
-       ret = resource_set_motor_driver_L298N_configuration(MOTOR_ID_1, 19, 16, 5);
+       ret = resource_set_motor_driver_L298N_configuration(MOTOR_ID_1, s_info.engine_1_forward_pin, s_info.engine_1_back_pin, s_info.engine_1_channel);
        if (ret) {
                _E("resource_set_motor_driver_L298N_configuration()");
                service_app_exit();
        }
-       ret = resource_set_motor_driver_L298N_configuration(MOTOR_ID_2, 26, 20, 4);
+       ret = resource_set_motor_driver_L298N_configuration(MOTOR_ID_2, s_info.engine_2_forward_pin, s_info.engine_2_back_pin, s_info.engine_2_channel);
        if (ret) {
                _E("resource_set_motor_driver_L298N_configuration()");
                service_app_exit();
        }
 #endif
 
-       receiver_init(RECEIVER_TYPE_UDP);
-       receiver_set_state_changed_cb(RECEIVER_TYPE_UDP, __recv_state_change, ad);
+       resource_lap_counter_init();
+       cloud_communication_start(CLOUD_REQUESTS_FREQUENCY);
 
-       connection_manager_init();
-       connection_manager_set_state_changed_cb(__conn_state_changed_cb, ad);
-       net_util_init();
+       controller_connection_manager_set_command_received_cb(__command_received_cb);
+       controller_connection_manager_set_user_name_received_cb(__user_name_received_cb);
 
-       message_queue_new();
+       resource_led_set_rgb_colors(CONFIG_LED_STATE_KEY_INIT,
+                       CONFIG_DEFAULT_LED_3BIT_INIT,
+                       CONFIG_DEFAULT_LED_24BIT_INIT,
+                       LED_COLOR_RED);
 
+       FUNCTION_END;
        return true;
 }
 
 static void service_app_control(app_control_h app_control, void *data)
 {
+       FUNCTION_START;
 
 #if ENABLE_MOTOR
        /* set speed 0, to reduce delay of initializing motor driver */
        resource_set_motor_driver_L298N_speed(MOTOR_ID_1, 0);
        resource_set_motor_driver_L298N_speed(MOTOR_ID_2, 0);
-       resource_set_servo_motor_value(0, 450);
+       resource_set_servo_motor_value(s_info.stering_pin, s_info.stering_center);
+       resource_set_servo_motor_value(s_info.elevation_pin, s_info.camera_elevation_min);
+       resource_set_servo_motor_value(s_info.azimuth_pin, s_info.camera_azimuth_center);
 #endif
 
+       FUNCTION_END;
        return;
 }
 
 static void service_app_terminate(void *data)
 {
        app_data *ad = data;
+       resource_led_set_rgb_colors(CONFIG_LED_STATE_KEY_OFF,
+                       CONFIG_DEFAULT_LED_3BIT_OFF,
+                       CONFIG_DEFAULT_LED_24BIT_OFF,
+                       LED_COLOR_NONE);
+
+       resource_set_servo_motor_value(s_info.stering_pin, s_info.stering_center);
+       resource_set_servo_motor_value(s_info.elevation_pin, s_info.camera_elevation_min);
+       resource_set_servo_motor_value(s_info.azimuth_pin, s_info.camera_azimuth_center);
+
+       resource_lap_counter_destroy();
+       resource_led_destroy();
 
        if (ad->idle_h)
                g_source_remove(ad->idle_h);
 
+       lap_counter_shutdown();
+       controller_connection_manager_release();
+       message_manager_shutdown();
 
-       connection_manager_fini();
+       cloud_communication_stop();
+       cloud_communication_fini();
+       config_shutdown();
        net_util_fini();
-       receiver_fini(RECEIVER_TYPE_UDP);
 
        resource_close_all();
        log_file_close();