| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294 |
- /*
- * Copyright (c) 2019, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2019-08-26 sogwms The first version
- */
- #include <command.h>
- #define DBG_SECTION_NAME "command"
- #define DBG_LEVEL DBG_LOG
- #include <rtdbg.h>
- // Thread
- #define THREAD_PRIORITY ((RT_THREAD_PRIORITY_MAX / 3) + 1)
- #define THREAD_STACK_SIZE 512
- #define THREAD_TIMESLICE 10
- static rt_thread_t cmd_tid = RT_NULL;
- //
- struct command_info
- {
- rt_uint16_t cmd;
- };
- typedef struct command_info *command_info_t;
- // Message Queue
- struct command_msg
- {
- struct command_info info;
- void *param;
- rt_uint16_t size;
- };
- #define MAX_MSGS 32
- static rt_mq_t cmd_mq = RT_NULL;
- // Target
- chassis_t g_chas;
- static rt_err_t command_handle_get(struct command_msg *msg)
- {
- switch (msg->info.cmd)
- {
- case COMMAND_GET_WHEEL0_PID:
- case COMMAND_GET_WHEEL1_PID:
- case COMMAND_GET_WHEEL2_PID:
- case COMMAND_GET_WHEEL3_PID:
- if (msg->size == sizeof(struct cmd_pid))
- {
- struct cmd_pid *ppid = msg->param;
- struct controller_param parameter;
- controller_get_param(g_chas->c_wheels[msg->info.cmd - COMMAND_GET_WHEEL0_PID]->w_controller, ¶meter);
- ppid->kp = parameter.data.pid.kp;
- ppid->ki = parameter.data.pid.ki;
- ppid->kd = parameter.data.pid.kd;
- }
- else
- {
- return RT_ERROR;
- }
- break;
- case COMMAND_GET_WHEELS_PID:
- if (msg->size >= 2 * sizeof(struct cmd_pid))
- {
- struct cmd_pid *ppid = msg->param;
- struct controller_param parameter;
- for (int i = 0; (i < g_chas->c_kinematics->total_wheels) && (i < (msg->size / sizeof(struct cmd_pid))); i++)
- {
- controller_get_param(g_chas->c_wheels[i]->w_controller, ¶meter);
- ppid[i].id = COMMAND_GET_WHEEL0_PID + i;
- ppid[i].kp = parameter.data.pid.kp;
- ppid[i].ki = parameter.data.pid.ki;
- ppid[i].kd = parameter.data.pid.kd;
- }
- }
- else
- {
- return RT_ERROR;
- }
- break;
-
- default: return RT_ERROR;
- }
- return RT_EOK;
- }
- rt_err_t command_handle(rt_uint16_t cmd, void *param, rt_uint16_t size)
- {
- struct command_msg msg = {
- .param = param,
- .size = size,
- .info = {
- .cmd = cmd,
- }
- };
- if (cmd > COMMAND_GET_START && cmd < COMMAND_GET_END)
- {
- return command_handle_get(&msg);
- }
- return rt_mq_send(cmd_mq, &msg, sizeof(struct command_msg));
- }
- rt_err_t command_send(command_sender_t sender, rt_uint16_t cmd, void *param, rt_uint16_t size)
- {
- if (sender->send != RT_NULL)
- {
- return sender->send(cmd, param, size);
- }
- return RT_ERROR;
- }
- static void command_thread_entry(void *param)
- {
- struct command_msg msg;
- while (1)
- {
- rt_mq_recv(cmd_mq, &msg, sizeof(struct command_msg), RT_WAITING_FOREVER);
- if (g_chas == RT_NULL)
- {
- LOG_D("The target is NULL");
- continue;
- }
- switch (msg.info.cmd)
- {
- case COMMAND_SET_WHEELS_PID:
- if (msg.size >= 2 * sizeof(struct cmd_pid))
- {
- struct cmd_pid *ppid = msg.param;
- struct controller_param parameter;
- for (int i = 0; i < g_chas->c_kinematics->total_wheels; i++)
- {
- parameter.data.pid.kp = ppid[i].kp;
- parameter.data.pid.ki = ppid[i].ki;
- parameter.data.pid.kd = ppid[i].kd;
- controller_set_param(g_chas->c_wheels[ppid[i].id]->w_controller, ¶meter);
- }
- }
- break;
- case COMMAND_SET_WHEEL0_PID:
- case COMMAND_SET_WHEEL1_PID:
- case COMMAND_SET_WHEEL2_PID:
- case COMMAND_SET_WHEEL3_PID:
- if (msg.size == sizeof(struct cmd_pid))
- {
- if (g_chas->c_kinematics->total_wheels > msg.info.cmd - COMMAND_SET_WHEEL0_PID)
- {
- struct cmd_pid *ppid = msg.param;
- struct controller_param parameter = {
- .data.pid.kp = ppid->kp,
- .data.pid.ki = ppid->ki,
- .data.pid.kd = ppid->kd
- };
- controller_set_param(g_chas->c_wheels[msg.info.cmd - COMMAND_SET_WHEEL0_PID]->w_controller, ¶meter);
- }
- }
- break;
- case COMMAND_SET_CHASSIS_STOP:
- chassis_move(g_chas, 0.0f);
- break;
- case COMMAND_SET_CHASSIS_FORWARD:
- chassis_straight(g_chas, CHASSIS_VELOCITY_LINEAR_MAXIMUM / 2.0f);
- break;
- case COMMAND_SET_CHASSIS_BACKWARD:
- chassis_straight(g_chas, -CHASSIS_VELOCITY_LINEAR_MAXIMUM / 2.0f);
- break;
- case COMMAND_SET_CHASSIS_ROTATE_LEFT:
- chassis_rotate(g_chas, CHASSIS_VELOCITY_ANGULAR_MAXIMUM / 2.0f);
- break;
- case COMMAND_SET_CHASSIS_ROTATE_RIGHT:
- chassis_rotate(g_chas, -CHASSIS_VELOCITY_ANGULAR_MAXIMUM / 2.0f);
- break;
- case COMMAND_SET_CHASSIS_MOVE_LEFT:
- chassis_move(g_chas, CHASSIS_VELOCITY_LINEAR_MAXIMUM / 2.0f);
- break;
- case COMMAND_SET_CHASSIS_MOVE_RIGHT:
- chassis_move(g_chas, -CHASSIS_VELOCITY_LINEAR_MAXIMUM / 2.0f);
- break;
- case COMMAND_SET_CHASSIS_FORWARD_WITH_PARAM:
- case COMMAND_SET_CHASSIS_BACKWARD_WITH_PARAM:
- case COMMAND_SET_CHASSIS_ROTATE_LEFT_WITH_PARAM:
- case COMMAND_SET_CHASSIS_ROTATE_RIGHT_WITH_PARAM:
- case COMMAND_SET_CHASSIS_MOVE_LEFT_WITH_PARAM:
- case COMMAND_SET_CHASSIS_MOVE_RIGHT_WITH_PARAM:
- if (msg.size == sizeof(struct cmd_velocity))
- {
- struct cmd_velocity *target_velocity = (struct cmd_velocity *)msg.param;
- rt_err_t (*p_fun)(chassis_t chas, float data);
- float tmp;
- if (msg.info.cmd == COMMAND_SET_CHASSIS_FORWARD_WITH_PARAM)
- {
- tmp = target_velocity->data.linear_x;
- p_fun = chassis_straight;
- }
- else if (msg.info.cmd == COMMAND_SET_CHASSIS_BACKWARD_WITH_PARAM)
- {
- tmp = -target_velocity->data.linear_x;
- p_fun = chassis_straight;
- }
- else if (msg.info.cmd == COMMAND_SET_CHASSIS_ROTATE_LEFT_WITH_PARAM)
- {
- tmp = target_velocity->data.angular_z;
- p_fun = chassis_rotate;
- }
- else if (msg.info.cmd == COMMAND_SET_CHASSIS_ROTATE_RIGHT_WITH_PARAM)
- {
- tmp = -target_velocity->data.angular_z;
- p_fun = chassis_rotate;
- }
- else if (msg.info.cmd == COMMAND_SET_CHASSIS_MOVE_LEFT_WITH_PARAM)
- {
- tmp = target_velocity->data.linear_y;
- p_fun = chassis_move;
- }
- else
- {
- tmp = -target_velocity->data.linear_y;
- p_fun = chassis_move;
- }
-
- p_fun(g_chas, tmp);
- }
- break;
- case COMMAND_SET_CHASSIS_VELOCITY_LINEAR_X:
- case COMMAND_SET_CHASSIS_VELOCITY_LINEAR_Y:
- case COMMAND_SET_CHASSIS_VELOCITY_ANGULAR_Z:
- if (msg.size == sizeof(struct cmd_velocity))
- {
- struct cmd_velocity *target_velocity = (struct cmd_velocity *)msg.param;
- rt_err_t (*p_fun)(chassis_t chas, float data);
- float tmp;
- if (msg.info.cmd == COMMAND_SET_CHASSIS_VELOCITY_LINEAR_X)
- {
- tmp = target_velocity->data.linear_x;
- p_fun = chassis_set_velocity_x;
- }
- else if (msg.info.cmd == COMMAND_SET_CHASSIS_VELOCITY_LINEAR_Y)
- {
- tmp = target_velocity->data.linear_y;
- p_fun = chassis_set_velocity_y;
- }
- else
- {
- tmp = target_velocity->data.angular_z;
- p_fun = chassis_set_velocity_z;
- }
- p_fun(g_chas, tmp);
- }
- break;
- default:
- break;
- }
- }
- }
- rt_err_t command_init(chassis_t chas)
- {
- cmd_mq = rt_mq_create("command", sizeof(struct command_msg), MAX_MSGS, RT_IPC_FLAG_FIFO);
- if (cmd_mq == RT_NULL)
- {
- LOG_E("Failed to creat meassage queue");
- return RT_ERROR;
- }
- cmd_tid = rt_thread_create("command",
- command_thread_entry, RT_NULL,
- THREAD_STACK_SIZE,
- THREAD_PRIORITY, THREAD_TIMESLICE);
- if (cmd_tid == RT_NULL)
- {
- LOG_E("Failed to creat thread");
- return RT_ERROR;
- }
- g_chas = chas;
- rt_thread_startup(cmd_tid);
- return RT_EOK;
- }
|