/* * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/license/ * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "model/model_car_connection.h" #include #include #include #include #include #include #include #include "command.h" #include "messages/message_manager.h" #include "car_connection_manager.h" #include "gear-racing-controller.h" #include "log.h" #define SEND_TIMEOUT 30 #define DIRECTION_BASE_VALUE 10000 #define THROTTLE_BASE_VALUE 10000 #define HELLO_TIMER_WAIT 3.0 typedef struct _s_car_model_connection { t_model_car_connection_update_cb controller_update_cb; bool ready_to_drive; char player_name[PLAYER_NAME_MAX_LEN + 1]; float direction; float throttle; float cam_elevation; float cam_azimuth; bool stop; bool is_app_paused; guint send_timer; } s_model_car_connection; s_model_car_connection s_info = { 0, }; void _connection_state_cb(car_connection_state_e previous, car_connection_state_e current); static void _send_data(int servo, int speed, int cam_azimuth, int cam_elevation) { command_s command = { .type = COMMAND_TYPE_DRIVE_AND_CAMERA, }; command.data.steering_and_camera.speed = speed; command.data.steering_and_camera.direction = servo; command.data.steering_and_camera.camera_azimuth = cam_azimuth; command.data.steering_and_camera.camera_elevation = cam_elevation; _FRAME_D("Sending command [speed: %d, direction: %d, cam_azim: %d, cam_elev: %d]", speed, servo, cam_azimuth, cam_elevation); car_connection_manager_send_command(command); } static gboolean _send_timer_cb(gpointer data) { if (s_info.is_app_paused) { _send_data(0, 0, 0, 0); } else { _send_data(s_info.direction * -DIRECTION_BASE_VALUE, s_info.throttle * THROTTLE_BASE_VALUE, s_info.cam_azimuth * -DIRECTION_BASE_VALUE, s_info.cam_elevation * -DIRECTION_BASE_VALUE); } return TRUE; } void model_car_connection_init(void) { message_manager_init(); car_connection_manager_init(); car_connection_manager_set_state_change_cb(_connection_state_cb); } void model_car_connection_subscribe_event(t_model_car_connection_update_cb model_update_cb) { s_info.controller_update_cb = model_update_cb; } void model_car_connection_unsubscirbe_event() { s_info.controller_update_cb = NULL; } void model_car_connection_start_connection(const char *address, int port) { if(car_connection_manager_connect(address, port)) { _E("Failed to connect with %s:%d", address, port); return; } } void model_car_connection_ready_to_drive(bool is_ready) { s_info.ready_to_drive = is_ready; } void model_car_connection_end_connection(void) { if(s_info.send_timer) { g_source_remove(s_info.send_timer); s_info.send_timer = 0; } car_connection_manager_disconnect(); } void model_car_connection_send_direction(float direction) { if (!s_info.ready_to_drive) { return; } s_info.direction = direction; } void model_car_connection_send_throttle(float throttle) { if (!s_info.ready_to_drive) { return; } if (s_info.stop) { s_info.throttle = 0; } else { s_info.throttle = throttle; } } void model_car_connection_send_cam_elevation(float cam_elevation) { if (!s_info.ready_to_drive) { return; } s_info.cam_elevation = cam_elevation; } void model_car_connection_send_cam_azimuth(float cam_azimuth) { if (!s_info.ready_to_drive) { return; } s_info.cam_azimuth = cam_azimuth; } void model_car_connection_set_stop(bool stop) { s_info.stop = stop; if (stop) { s_info.throttle = 0; } } bool model_car_connection_is_connected() { return CAR_CONNECTION_STATE_CONNECTED == car_connection_manager_get_state(); } bool model_car_connection_player_name_set(const char *player_name) { if(!model_car_connection_is_connected()) { _E("Connection hasn't been established"); return false; } strncpy(s_info.player_name, player_name, PLAYER_NAME_MAX_LEN); car_connection_manager_send_user_name(s_info.player_name); return true; } void _connection_state_cb(car_connection_state_e previous, car_connection_state_e current) { static s_model_car_connection_cb_data model_data; if(current == CAR_CONNECTION_STATE_CONNECTING) { model_data.type = MODEL_TYPE_WAIT; } else if(current == CAR_CONNECTION_STATE_DISCONNECTED) { if(s_info.send_timer) { g_source_remove(s_info.send_timer); } model_data.type = MODEL_TYPE_FAIL; } else { s_info.send_timer = g_timeout_add(SEND_TIMEOUT, _send_timer_cb, NULL); model_data.type = MODEL_TYPE_END; } if (s_info.controller_update_cb) { s_info.controller_update_cb(&model_data); } } void model_car_connection_set_paused(bool is_paused) { s_info.is_app_paused = is_paused; }