25_R1_chassis/User/device/remote_control.c
2025-05-25 20:10:14 +08:00

257 lines
8.3 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Includes ----------------------------------------------------------------- */
#include "remote_control.h"
#include <string.h>
#include "bsp_usart.h"
#include "error_detect.h"
//两个遥控器都是
// x
// |
// |
// ———y
//在这下面更换遥控器
#define DR16
//#define R12DS
#ifdef DR16
#define FRAME_LEN 36
#endif
#ifdef R12DS
#define FRAME_LEN 25
#endif
/* Private define ----------------------------------------------------------- */
#define REMOTE_CH_VALUE_MIN (364u)
#define REMOTE_CH_VALUE_MID (1024u)
#define REMOTE_CH_VALUE_MAX (1684u)
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
/* Private variables -------------------------------------------------------- */
static osThreadId_t thread_alert;
uint8_t cbuf[FRAME_LEN]; //此处设置为两帧字节的长度 若为一帧会出现乱码的情况
/* Private function -------------------------------------------------------- */
int8_t REMOTE_Restart(void) {
__HAL_UART_DISABLE(BSP_UART_GetHandle(BSP_UART_REMOTE));
__HAL_UART_ENABLE(BSP_UART_GetHandle(BSP_UART_REMOTE));
return DEVICE_OK;
}
static void REMOTE_RxCpltCallback(void) {
osThreadFlagsSet(thread_alert, SIGNAL_DR16_RAW_REDY);
//detect_hook(DR16_TOE);
}
//遥控器初始化
int8_t REMOTE_Init(void) {
if ((thread_alert = osThreadGetId()) == NULL) return DEVICE_ERR_NULL;
BSP_UART_RegisterCallback(BSP_UART_REMOTE, BSP_UART_IDLE_LINE_CB,
REMOTE_RxCpltCallback);
memset(cbuf, 0, sizeof(cbuf));//初始化清空数据包
return DEVICE_OK;
}
int8_t REMOTE_StartDmaRecv(void) {
if (HAL_UARTEx_ReceiveToIdle_DMA(BSP_UART_GetHandle(BSP_UART_REMOTE),
(uint8_t *)cbuf,
sizeof(cbuf)) == HAL_OK)
return DEVICE_OK;
return DEVICE_ERR;
}
bool REMOTE_WaitDmaCplt(uint32_t timeout) {
return (osThreadFlagsWait(SIGNAL_DR16_RAW_REDY, osFlagsWaitAll, timeout) ==
SIGNAL_DR16_RAW_REDY);
}
/*大疆数据解析 */
static bool DR16_DataCorrupted(const DR16_t *dr16) {
if (dr16 == NULL) return DEVICE_ERR_NULL;
if ((dr16->data.ch_r_x < REMOTE_CH_VALUE_MIN) ||
(dr16->data.ch_r_x > REMOTE_CH_VALUE_MAX))
return true;
if ((dr16->data.ch_r_y < REMOTE_CH_VALUE_MIN) ||
(dr16->data.ch_r_y > REMOTE_CH_VALUE_MAX))
return true;
if ((dr16->data.ch_l_x < REMOTE_CH_VALUE_MIN) ||
(dr16->data.ch_l_x > REMOTE_CH_VALUE_MAX))
return true;
if ((dr16->data.ch_l_y < REMOTE_CH_VALUE_MIN) ||
(dr16->data.ch_l_y > REMOTE_CH_VALUE_MAX))
return true;
if (dr16->data.sw_l == 0) return true;
if (dr16->data.sw_r == 0) return true;
return false;
}
int8_t DR16_ParseRaw(DR16_t *dr16){
if(dr16 ==NULL) return DEVICE_ERR_NULL;
dr16->data.ch_r_x = (cbuf[0] | (cbuf[1] <<8));
dr16->data.ch_r_y = ((cbuf[1] >> 3)| (cbuf[2] << 5));
dr16->data.ch_l_x = ((cbuf[2] >>6) | (cbuf[3] << 2) | (cbuf[4] <<10));
dr16->data.ch_l_y = ((cbuf[4] >>1) | (cbuf[5] <<7));
dr16->data.sw_r = ((cbuf[5] >>4));
dr16->data.sw_l = ((cbuf[5] >> 4) & 0x000C) >> 2;
return 1;
}
/*乐迪数据解析 */
/*乐迪用的按键封装 */
CMD_SwitchPos_t Keymap(int16_t value) {
return (value > 300 && value < 500) ? CMD_SW_DOWN :
(value >= 500 && value < 1500) ? CMD_SW_MID :
(value >= 1500 && value < 1700) ? CMD_SW_UP : CMD_SW_ERR;
}
int8_t LD_ParseRaw( LD_raw_t *raw){
raw->ch[0] = (cbuf[1] | (cbuf[2] << 8)) & 0x07ff; //Channel 1
raw->ch[1] = ((cbuf[2] >> 3) | (cbuf[3] << 5)) & 0x07ff; //Channel 2
raw->ch[2] = ((cbuf[3] >> 6) | (cbuf[4] << 2) | (cbuf[5] << 10)) &0x07ff; //Channel 3
raw->ch[3] = ((cbuf[5] >> 1) | (cbuf[6] << 7)) & 0x07ff; //Channel 4
raw->sw[0] = ((int16_t)cbuf[6] >> 4 | ((int16_t)cbuf[7] << 4 )) & 0x07FF;//Channel 5
raw->sw[1] = ((int16_t)cbuf[7] >> 7 | ((int16_t)cbuf[8] << 1 ) | (int16_t)cbuf[9] << 9 ) & 0x07FF;//Channel 6
raw->sw[2] = ((int16_t)cbuf[9] >> 2 | ((int16_t)cbuf[10] << 6 )) & 0x07FF;;//Channel 7
raw->sw[3] = ((int16_t)cbuf[10] >> 5 | ((int16_t)cbuf[11] << 3 )) & 0x07FF;//Channel 8
raw->sw[4] = ((int16_t)cbuf[12] << 0 | ((int16_t)cbuf[13] << 8 )) & 0x07FF;//Channel 9
raw->sw[5] = ((int16_t)cbuf[13] >> 3 | ((int16_t)cbuf[14] << 5 )) & 0x07FF;//Channel 10
raw->sw[6] = ((int16_t)cbuf[14] >> 6 | ((int16_t)cbuf[15] << 2 ) | (int16_t)cbuf[16] << 10 ) & 0x07FF;//Channel 11
raw->sw[7] = ((int16_t)cbuf[16] >> 1 | ((int16_t)cbuf[17] << 7 )) & 0x07FF;//Channel 12
raw->ch[0] -= REMOTE_CH_VALUE_MID;
raw->ch[1] -= REMOTE_CH_VALUE_MID;
raw->ch[2] -= REMOTE_CH_VALUE_MID;
raw->ch[3] -= REMOTE_CH_VALUE_MID;
raw->ch[0] = +raw->ch[0];
raw->ch[1] = -raw->ch[1];
raw->ch[2] = -raw->ch[2];
raw->ch[3] = +raw->ch[3];
//中心平移
raw->ch[0] += 24.5; //(-693.5,693.5)
raw->ch[1] -= 24.5; //(-693.5,693.5)
raw->ch[2] -= 125; //(-693,693)
raw->ch[3] += 24.5; //(-693.5,693.5)
return 1;
/*
306 306
sw[] sw[7]
1694 1694
306 306
sw[6] sw[4]
1694 1694
306 306 306 306
sw[0] sw[2] sw[1] sw[5] sw[]1000 nsw[3]
1694 1694 306-1694 306-1694 1694 1694
818 718
| |
| |
-718----------ch[3]669 -718---------ch[0] 669
| |
| |
ch[2] ch[1]
-568 -669
*/
}
int8_t REMOTE_ParseRC(DR16_t *dr16, CMD_RC_t *rc,LD_raw_t *LD) {
if (dr16 == NULL) return DEVICE_ERR_NULL;
if (LD == NULL) return DEVICE_ERR_NULL;
#ifdef DR16
rc->rc_type=RC_DR16;
DR16_ParseRaw(dr16);
if (DR16_DataCorrupted(dr16)) {
return DEVICE_ERR;
} else {
memset(rc, 0, sizeof(*rc));
}
float full_range = (float)(REMOTE_CH_VALUE_MAX - REMOTE_CH_VALUE_MIN);
rc->DJ.ch_r_x = 2 * ((float)dr16->data.ch_r_y - REMOTE_CH_VALUE_MID) / full_range;
rc->DJ.ch_r_y = 2 * ((float)dr16->data.ch_r_x - REMOTE_CH_VALUE_MID) / full_range;
rc->DJ.ch_l_x = 2 * ((float)dr16->data.ch_l_y - REMOTE_CH_VALUE_MID) / full_range;
rc->DJ.ch_l_y = 2 * ((float)dr16->data.ch_l_x - REMOTE_CH_VALUE_MID) / full_range;
rc->DJ.sw_l = (CMD_SwitchPos_t)dr16->data.sw_l;
rc->DJ.sw_r = (CMD_SwitchPos_t)dr16->data.sw_r;
// rc->dr16.key = dr16->data.key;
// rc->ch_res = ((float)dr16->data.res - DR16_CH_VALUE_MID) / full_range;
#elif defined(R12DS)
/*乐迪*/
rc->rc_type=RC_LD;
LD_ParseRaw(LD);
//memcpy(&rc->LD, LD, sizeof(LD_Data_t));
rc->LD.ch_r_x = (float)LD->ch[1] /693.5f;
rc->LD.ch_r_y = (float)LD->ch[0] /693.5f;
rc->LD.ch_l_x = (float)LD->ch[2] /693;
rc->LD.ch_l_y = (float)LD->ch[3] /693.5f;
rc->LD.key_A = Keymap(LD->sw[0]);
rc->LD.key_C = Keymap(LD->sw[2]);
rc->LD.key_E = Keymap(LD->sw[5]);
rc->LD.key_F = Keymap(LD->sw[3]);
rc->LD.key_G = Keymap(LD->sw[7]);
rc->LD.key_H = Keymap(LD->sw[4]);
rc->LD.knob_left = Keymap(LD->sw[1]);
rc->LD.knob_right = Keymap(LD->sw[6]);
// /*离线处理和dr16位置不同*/
if(LD->sw[6]!=1694)
{
LD_HandleOffline(LD,rc);
// memset(cbuf, 0, sizeof(cbuf)); //有时候会出现消息数组错位,所以直接清空,在离线和指定按键不对的情况下,原数据不可信
}
#endif
return DEVICE_OK;
}
int8_t DR16_HandleOffline(const DR16_t *dr16, CMD_RC_t *rc) {
if (dr16 == NULL) return DEVICE_ERR_NULL;
if (rc == NULL) return DEVICE_ERR_NULL;
rc->rc_type =Control_loss ;
memset(&rc->DJ , 0, sizeof(DR16_t));
return 0;
}
int8_t LD_HandleOffline(const LD_raw_t *LD, CMD_RC_t *rc) {
if (LD == NULL) return DEVICE_ERR_NULL;
if (rc == NULL) return DEVICE_ERR_NULL;
rc->rc_type =Control_loss ;
memset(&rc->LD , 0, sizeof(LD_raw_t));
return 0;
}