Merge remote-tracking branch 'origin/main' into integrate_arm_chassis_20260320
This commit is contained in:
commit
d71dbde8d8
@ -1,314 +1,460 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
µ×ÅÌÄ£×é
|
底盘任务
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
舵轮底盘模组
|
||||||
|
example:
|
||||||
|
Chassis_t chassis;
|
||||||
|
Chassis_CMD_t cmd_chassis;
|
||||||
|
|
||||||
|
chassis_init(&chassis,&Config_GetRobotParam()->chassis,CHASSIS_FREQ);
|
||||||
|
|
||||||
|
osMessageQueueGet(task_runtime.msgq.imu.eulr, &chassis.pos088.imu_eulr, NULL, 0);
|
||||||
|
osMessageQueueGet(task_runtime.msgq.imu.gyro, &chassis.pos088.bmi088.gyro, NULL, 0);
|
||||||
|
这个是用来调防翻的,可以不用,而且需要c板放在地盘不能在云台上面
|
||||||
|
|
||||||
|
osMessageQueueGet(task_runtime.msgq.gimbal.yaw6020,&chassis.motorfeedback.gimbal_yaw_encoder,NULL,0);
|
||||||
|
|
||||||
|
if(osMessageQueueGet(task_runtime.msgq.cmd.chassis, &cmd_chassis, NULL, 0)==osOK)
|
||||||
|
{
|
||||||
|
Chassis_update(&chassis);
|
||||||
|
Chassis_Control(&chassis, &cmd_chassis,tick);
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
Chassis_CMD_t safe_cmd = {.mode = STOP, .Vx = 0, .Vy = 0, .Vw = 0};
|
||||||
|
Chassis_Control(&chassis, &safe_cmd);
|
||||||
|
}
|
||||||
|
Chassis_Setoutput(&chassis);
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cmsis_os2.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "bsp/mm.h"
|
/* Includes ----------------------------------------------------------------- */
|
||||||
#include "bsp/can.h"
|
#include "chassis.h"
|
||||||
#include "component/ahrs.h"
|
|
||||||
#include "device/motor_rm.h"
|
#include "device/motor_rm.h"
|
||||||
#include "device/motor.h"
|
#include "bsp/time.h"
|
||||||
#include "module/chassis.h"
|
#include "bsp/can.h"
|
||||||
#include "component/PowerControl.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
/**
|
#include "component/pid.h"
|
||||||
* @brief µ×ÅÌСÍÓÂÝģʽÏà¹Ø²ÎÊý
|
#include "component/filter.h"
|
||||||
*/
|
#include "stdlib.h"
|
||||||
#define CHASSIS_ROTOR_WZ_MIN 0.6f //СÍÓÂÝ×îСËÙ¶È
|
/*舵轮舵向校准方法:注释掉关于6020反馈角度的处理以及6020数据的发送这两处(define.h里有快捷方法),
|
||||||
#define CHASSIS_ROTOR_WZ_MAX 0.8f //СÍÓÂÝ×î´óËÙ¶È
|
进debug将四个轮子编码器朝右(左右无所谓,可能会导致5065方向反,在解算里加个负号就行)
|
||||||
#define M_7OVER72PI (M_2PI * 7.0f / 72.0f) //½Ç¶ÈÆ«ÒÆÁ¿£¨ÓÃÔÚ¸úËæÔÆÌ¨35¡ã£©
|
查看6020反馈值,将6020反馈值放入motor_offset中*/
|
||||||
#define CHASSIS_ROTOR_OMEGA 0.001f //½ÇËٶȱ仯ƵÂÊ
|
|
||||||
|
|
||||||
|
/*chassis_t结构体中的内容现在有 move_vec (最终输出速度)
|
||||||
|
hopemotorout(期望的底盘输出值)舵轮解算出的各个电机的期望输出值 包括四个6020 和四个3508
|
||||||
|
final_out;(经PID计算后的实际发送给电机的实时输出值) 四个6020 四个3508
|
||||||
|
motorfeedback(电机反馈数据) 四个3508 四个6020
|
||||||
|
pid 各个电机的pid参数
|
||||||
|
ChassisImu_t pos088; 088的实时姿态
|
||||||
|
MotorOffset_t motoroffset; //6020校准数据
|
||||||
|
const Chassis_Param_t *param; //一些固定的参数
|
||||||
|
fp32 vofa_send[8]; //vofa输出数据
|
||||||
|
LowPassFilter2p_t filled[9]; //低通滤波器
|
||||||
|
float keep_angle[4]; // 保持的 6020 角度
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Private typedef ---------------------------------------------------------- */
|
||||||
|
#define CHASSIS_ROTOR_OMEGA 0.001
|
||||||
|
#define CHASSIS_ROTOR_WZ_MIN 0.6f /* 小陀螺旋转位移下界 */
|
||||||
|
#define CHASSIS_ROTOR_WZ_MAX 0.8f /* 小陀螺旋转位移上界 */
|
||||||
|
#define ONE_MINUTE 60.0f /* 一分钟时间 */
|
||||||
|
|
||||||
/**
|
static int8_t Chassis_SetMode(Chassis_t *c, Chassis_Mode_t mode ,uint32_t now)
|
||||||
* @brief ÉèÖõ×ÅÌģʽ
|
{
|
||||||
* @param c µ×Å̽ṹÌåÖ¸Õë
|
if (c == NULL)
|
||||||
* @param mode Ä¿±ê¿ØÖÆÄ£Ê½
|
return CHASSIS_ERR_NULL; /* 主结构体不能为空 */
|
||||||
* @param now µ±Ç°Ê±¼ä´Á(ms)
|
if (mode == c->mode) return CHASSIS_OK; /* 模式未改变直接返回 */
|
||||||
* @return CHASSIS_OK:³É¹¦ CHASSIS_ERR_NULL:¿Õ
|
|
||||||
*/
|
|
||||||
static int8_t Chassis_SetMode(Chassis_t *c, Chassis_Mode_t mode, uint32_t now) {
|
|
||||||
if (!c)
|
|
||||||
return CHASSIS_ERR_NULL;
|
|
||||||
if (mode == c->mode)
|
|
||||||
return CHASSIS_OK;
|
|
||||||
//Ëæ»úÖÖ×Ó£¬Ð¡ÍÓÂÝÄ£Ê½Ëæ»úÉèÖÃÐýת·½Ïò
|
|
||||||
if (mode == CHASSIS_MODE_ROTOR && c->mode != CHASSIS_MODE_ROTOR) {
|
|
||||||
srand(now);
|
|
||||||
c->wz_multi = (rand() % 2) ? -1 : 1;
|
|
||||||
}
|
|
||||||
//ÖØÖÃPIDºÍÂ˲¨
|
|
||||||
for (uint8_t i = 0; i < c->num_wheel; i++) {
|
|
||||||
PID_Reset(&c->pid.motor[i]);
|
|
||||||
LowPassFilter2p_Reset(&c->filter.in[i], 0.0f);
|
|
||||||
LowPassFilter2p_Reset(&c->filter.out[i], 0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
c->mode = mode;
|
if (mode == CHASSIS_MODE_ROTOR && c->mode != CHASSIS_MODE_ROTOR) {
|
||||||
return CHASSIS_OK;
|
srand(now);
|
||||||
|
c->wz_multi =1;
|
||||||
|
// c->wz_multi = (rand() % 2) ? -1 : 1;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
PID_Reset(&c->pid.Radder_DIR_omega[i]);
|
||||||
|
PID_Reset(&c->pid.Radder_DIR_angle[i]);
|
||||||
|
PID_Reset(&c->pid.Wheel_DIR_omega[i]);
|
||||||
|
PID_Reset(&c->pid.Radder_DIR_omega[i]);
|
||||||
|
}
|
||||||
|
c->mode = mode;
|
||||||
|
return CHASSIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief СÍÓÂÝģʽ¶¯Ì¬½ÇËÙ¶È
|
* @brief 产生小陀螺wz随机速度
|
||||||
* @param min ×îСËÙ¶È
|
*
|
||||||
* @param max ×î´óËÙ¶È
|
* @param min wz产生最小速度
|
||||||
* @param now µ±Ç°Ê±¼ä´Á(ms)
|
* @param max wz产生最大速度
|
||||||
* @return ½ÇËÙ¶ÈÖµ
|
* @param now ctrl_chassis的tick数
|
||||||
|
* @return float
|
||||||
*/
|
*/
|
||||||
static float Chassis_CalcWz(const float min, const float max, uint32_t now) {
|
static float Chassis_CalcWz(const float min, const float max, uint32_t now) {
|
||||||
float wz_vary = fabsf(0.2f * sinf(CHASSIS_ROTOR_OMEGA * (float)now)) + min;
|
/* wz在min和max之间,上限0.6f */
|
||||||
return (wz_vary > max) ? max : wz_vary;
|
float wz_vary = fabs(0.2f * sinf(CHASSIS_ROTOR_OMEGA * (float)now)) + min;
|
||||||
|
return wz_vary > 0.8f ? max : wz_vary;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*底盘初始化*/
|
||||||
* @brief µ×ÅÌģʽ³õʼ»¯
|
|
||||||
* @param c µ×Å̽ṹÌåÖ¸Õë
|
|
||||||
* @param param µ×Å̲ÎÊý½á¹¹ÌåÖ¸Õë
|
|
||||||
* @param mech_zero »úеÁãµãÅ·À½Ç
|
|
||||||
* @param target_freq ¿ØÖÆÆµÂÊ(Hz)
|
|
||||||
* @return CHASSIS_OK:³É¹¦ CHASSIS_ERR_NULL:¿Õ CHASSIS_ERR_TYPE:²»Ö§³ÖµÄģʽ
|
|
||||||
*/
|
|
||||||
int8_t Chassis_Init(Chassis_t *c, const Chassis_Params_t *param,
|
|
||||||
float target_freq) {
|
|
||||||
if (!c) return CHASSIS_ERR_NULL;
|
|
||||||
|
|
||||||
//³õʼ»¯CANͨÐÅ
|
int8_t chassis_init(Chassis_t *c, Chassis_Param_t *param, float target_freq)
|
||||||
BSP_CAN_Init();
|
|
||||||
c->param = param;
|
|
||||||
c->mode = CHASSIS_MODE_RELAX;
|
|
||||||
//¸ù¾Ýµ×Å̲»Í¬ÉèÖÃģʽÂÖ×ÓÓë»ìºÏÆ÷
|
|
||||||
Mixer_Mode_t mixer_mode;
|
|
||||||
switch (param->type) {
|
|
||||||
case CHASSIS_TYPE_MECANUM://ÂóÂÖ
|
|
||||||
c->num_wheel = 4;
|
|
||||||
mixer_mode = MIXER_MECANUM;
|
|
||||||
break;
|
|
||||||
case CHASSIS_TYPE_PARLFIX4:
|
|
||||||
c->num_wheel = 4;
|
|
||||||
mixer_mode = MIXER_PARLFIX4;
|
|
||||||
break;
|
|
||||||
case CHASSIS_TYPE_PARLFIX2:
|
|
||||||
c->num_wheel = 2;
|
|
||||||
mixer_mode = MIXER_PARLFIX2;
|
|
||||||
break;
|
|
||||||
case CHASSIS_TYPE_OMNI_CROSS:
|
|
||||||
c->num_wheel = 4;
|
|
||||||
mixer_mode = MIXER_OMNICROSS;
|
|
||||||
break;
|
|
||||||
case CHASSIS_TYPE_OMNI_PLUS: //È«ÏòÂÖ£¨Àϲ½±øÀàÐÍ£©
|
|
||||||
c->num_wheel = 4;
|
|
||||||
mixer_mode = MIXER_OMNIPLUS;
|
|
||||||
break;
|
|
||||||
case CHASSIS_TYPE_SINGLE:
|
|
||||||
c->num_wheel = 1;
|
|
||||||
mixer_mode = MIXER_SINGLE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return CHASSIS_ERR_TYPE;
|
|
||||||
}
|
|
||||||
//³õʼ»¯Ê±¼ä´Á
|
|
||||||
c->last_wakeup = 0;
|
|
||||||
c->dt = 0.0f;
|
|
||||||
//³õʼ»¯PIDºÍÂ˲¨
|
|
||||||
for (uint8_t i = 0; i < c->num_wheel; i++) {
|
|
||||||
PID_Init(&c->pid.motor[i], KPID_MODE_NO_D, target_freq, ¶m->pid.motor_pid_param);
|
|
||||||
LowPassFilter2p_Init(&c->filter.in[i], target_freq, param->low_pass_cutoff_freq.in);
|
|
||||||
LowPassFilter2p_Init(&c->filter.out[i], target_freq, param->low_pass_cutoff_freq.out);
|
|
||||||
//ÇåÁãµç»ú·´À¡
|
|
||||||
c->feedback.motor[i].rotor_speed = 0;
|
|
||||||
c->feedback.motor[i].torque_current = 0;
|
|
||||||
c->feedback.motor[i].rotor_abs_angle = 0;
|
|
||||||
c->feedback.motor[i].temp = 0;
|
|
||||||
}
|
|
||||||
//³õʼ»¯PIDºÍ»ìºÏÆ÷
|
|
||||||
PID_Init(&c->pid.follow, KPID_MODE_CALC_D, target_freq, ¶m->pid.follow_pid_param);
|
|
||||||
Mixer_Init(&c->mixer, mixer_mode);
|
|
||||||
//ÇåÁãÔ˶¯ÏòÁ¿ºÍÊä³ö
|
|
||||||
c->move_vec.vx = c->move_vec.vy = c->move_vec.wz = 0.0f;
|
|
||||||
for (uint8_t i = 0; i < c->num_wheel; i++) {
|
|
||||||
c->out.motor[i] = 0.0f;
|
|
||||||
}
|
|
||||||
//×¢²á´ó½®µç»ú
|
|
||||||
for (int i = 0; i < c->num_wheel; i++) {
|
|
||||||
MOTOR_RM_Register(&(c->param->motor_param[i]));
|
|
||||||
|
|
||||||
}
|
|
||||||
return CHASSIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief ¸üеç»ú·´À¡(IMU+µç»ú״̬)
|
|
||||||
* @param c µ×Å̽ṹÌåÖ¸Õë
|
|
||||||
* @param feedback µ×ÅÌ·´À¡Ö¸Õë½á¹¹Ìå
|
|
||||||
* @return CHASSIS_OK:³É¹¦ CHASSIS_ERR_NULL:¿Õ
|
|
||||||
*/
|
|
||||||
int8_t Chassis_UpdateFeedback(Chassis_t *c) {
|
|
||||||
|
|
||||||
|
|
||||||
//¸üÐÂËùÓеç»ú·´À¡
|
|
||||||
for (uint8_t i = 0; i < c->num_wheel; i++) {
|
|
||||||
MOTOR_RM_Update(&(c->param->motor_param[i]));
|
|
||||||
MOTOR_RM_t *rm_motor = MOTOR_RM_GetMotor(&(c->param->motor_param[i]));
|
|
||||||
c->motors[i] = rm_motor;
|
|
||||||
MOTOR_RM_t *rm = c->motors[i];
|
|
||||||
if (rm_motor != NULL) {
|
|
||||||
c->feedback.motor[i] = rm_motor->feedback;
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
return CHASSIS_ERR_NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return CHASSIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief µ×Å̵ç»ú¿ØÖÆ
|
|
||||||
* @param c µ×Å̽ṹÌåÖ¸Õë
|
|
||||||
* @param c_cmd ¿ØÖÆÃüÁî
|
|
||||||
* @param now µ±Ç°Ê±¼ä´Á(ms)
|
|
||||||
* @return CHASSIS_OK:³É¹¦ CHASSIS_ERR_NULL:¿Õ
|
|
||||||
*/
|
|
||||||
int8_t Chassis_Control(Chassis_t *c, const Chassis_CMD_t *c_cmd, uint32_t now) {
|
|
||||||
if (!c || !c_cmd) return CHASSIS_ERR_NULL;
|
|
||||||
//¼ÆËã¿ØÖÆÖÜÆÚ
|
|
||||||
c->dt = (float)(now - c->last_wakeup) / 1000.0f;
|
|
||||||
c->last_wakeup = now;
|
|
||||||
if (!isfinite(c->dt) || c->dt <= 0.0f) {
|
|
||||||
c->dt = 0.001f;
|
|
||||||
}
|
|
||||||
if (c->dt < 0.0005f) c->dt = 0.0005f;
|
|
||||||
if (c->dt > 0.050f) c->dt = 0.050f;
|
|
||||||
//ÉèÖÃģʽ
|
|
||||||
Chassis_SetMode(c, c_cmd->mode, now);
|
|
||||||
//²»Í¬Ä£Ê½Ï¶ÔÓ¦½âË㣨Ô˶¯ÏòÁ¿£©
|
|
||||||
switch (c->mode) {
|
|
||||||
case CHASSIS_MODE_BREAK:
|
|
||||||
c->move_vec.vx = c->move_vec.vy = 0.0f;
|
|
||||||
break;
|
|
||||||
case CHASSIS_MODE_INDEPENDENT:
|
|
||||||
c->move_vec.vx = c_cmd->ctrl_vec.vx;
|
|
||||||
c->move_vec.vy = c_cmd->ctrl_vec.vy;
|
|
||||||
break;
|
|
||||||
default: { //Ò£¿ØÆ÷×ø±ê->»úÌå×ø±êϵ
|
|
||||||
float beta = c->feedback.encoder_gimbalYawMotor - c->mech_zero;
|
|
||||||
float cosb = cosf(beta);
|
|
||||||
float sinb = sinf(beta);
|
|
||||||
c->move_vec.vx = cosb * c_cmd->ctrl_vec.vx - sinb * c_cmd->ctrl_vec.vy;
|
|
||||||
c->move_vec.vy = sinb * c_cmd->ctrl_vec.vx + cosb * c_cmd->ctrl_vec.vy;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//¸ù¾Ýģʽ¼ÆËãµ×Å̽ÇËÙ¶È
|
|
||||||
switch (c->mode) {
|
|
||||||
case CHASSIS_MODE_RELAX:
|
|
||||||
case CHASSIS_MODE_BREAK:
|
|
||||||
case CHASSIS_MODE_INDEPENDENT:
|
|
||||||
c->move_vec.wz = c_cmd->ctrl_vec.wz;
|
|
||||||
break;
|
|
||||||
case CHASSIS_MODE_OPEN:
|
|
||||||
c->move_vec.wz = c_cmd->ctrl_vec.wz;
|
|
||||||
break;
|
|
||||||
//ÔÆÌ¨¸úËæ
|
|
||||||
case CHASSIS_MODE_FOLLOW_GIMBAL:
|
|
||||||
c->move_vec.wz = PID_Calc(&c->pid.follow, c->mech_zero, c->feedback.encoder_gimbalYawMotor, 0.0f, c->dt);
|
|
||||||
break;
|
|
||||||
//ÔÆÌ¨¸úËæ£¨Æ«ÒÆ£©
|
|
||||||
case CHASSIS_MODE_FOLLOW_GIMBAL_35:
|
|
||||||
c->move_vec.wz = PID_Calc(&c->pid.follow,c->mech_zero +M_7OVER72PI, c->feedback.encoder_gimbalYawMotor, 0.0f, c->dt);
|
|
||||||
break;
|
|
||||||
//СÍÓÂÝ
|
|
||||||
case CHASSIS_MODE_ROTOR:
|
|
||||||
c->move_vec.wz = c->wz_multi * Chassis_CalcWz(CHASSIS_ROTOR_WZ_MIN,CHASSIS_ROTOR_WZ_MAX, now);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//Ô˶¯Ñ§Äæ½âË㣬Ô˶¯ÏòÁ¿·Ö½âΪµç»úתËÙ
|
|
||||||
Mixer_Apply(&c->mixer, &c->move_vec, c->setpoint.motor_rpm, c->num_wheel, 500.0f);
|
|
||||||
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < c->num_wheel; i++) {
|
|
||||||
float rf = c->setpoint.motor_rpm[i];///Ä¿±êתËÙ
|
|
||||||
float fb = LowPassFilter2p_Apply(&c->filter.in[i], (float)c->feedback.motor[i].rotor_speed);
|
|
||||||
float out_current;
|
|
||||||
switch (c->mode) {
|
|
||||||
case CHASSIS_MODE_BREAK:
|
|
||||||
case CHASSIS_MODE_FOLLOW_GIMBAL:
|
|
||||||
case CHASSIS_MODE_FOLLOW_GIMBAL_35:
|
|
||||||
case CHASSIS_MODE_ROTOR:
|
|
||||||
case CHASSIS_MODE_INDEPENDENT:
|
|
||||||
out_current = PID_Calc(&c->pid.motor[i], c->setpoint.motor_rpm[i], fb, 0.0f, c->dt);
|
|
||||||
break;
|
|
||||||
case CHASSIS_MODE_OPEN:
|
|
||||||
out_current = c->setpoint.motor_rpm[i] / 7000.0f;
|
|
||||||
break;
|
|
||||||
case CHASSIS_MODE_RELAX:
|
|
||||||
out_current = 0.0f;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//µÍͨÂ˲¨ºÍÏÞ·ù
|
|
||||||
c->out.motor[i] = LowPassFilter2p_Apply(&c->filter.out[i], out_current);
|
|
||||||
Clip(&c->out.motor[i], -c->param->limit.max_current, c->param->limit.max_current);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return CHASSIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Chassis_Power_Control(Chassis_t *c,float max_power)
|
|
||||||
{
|
{
|
||||||
float* rpm=(float[4]){c->motors[0]->feedback.rotor_speed,c->motors[1]->feedback.rotor_speed,c->motors[2]->feedback.rotor_speed,c->motors[3]->feedback.rotor_speed};
|
if (c == NULL || param == NULL || target_freq <= 0.0f)
|
||||||
power_model_t* param = (c->mode == CHASSIS_MODE_ROTOR) ? &cha2 : &cha;
|
{
|
||||||
power_calu(param,(float[4]){c->out.motor[0],c->out.motor[1],c->out.motor[2],c->out.motor[3]},rpm);
|
return CHASSIS_ERR; // 参数错误
|
||||||
float scale = power_scale_calu(¶m,1,max_power);
|
}
|
||||||
power_out_calu(param,scale,(float[4]){c->out.motor[0],c->out.motor[1],c->out.motor[2],c->out.motor[3]},rpm,c->out.motor);
|
c->param = param;
|
||||||
|
c->mode = CHASSIS_MODE_RELAX; // 默认模式为停止锁死底盘
|
||||||
|
c->mech_zero = c->param->mech_zero;/*云台6020的机械中点*/
|
||||||
|
c->travel = c->param->travel ;/*云台6020的机械行程*/
|
||||||
|
// c->mech_zero_4310 = c->param->mech_zero_4310;/*云台4310的机械中点*/
|
||||||
|
/*初始化can*/
|
||||||
|
BSP_CAN_Init();
|
||||||
|
/*注册轮向电机*/
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
MOTOR_RM_Register(&(c->param->motor.Wheel_DIR[i]));
|
||||||
|
}
|
||||||
|
/*注册舵向电机*/
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
MOTOR_RM_Register(&(c->param->motor.Radder_DIR[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 舵轮安装时的6020机械误差,机械校准时1号轮在左前方,所有轮的编码器朝向右面
|
||||||
|
MotorOffset_t motor_offset = {{5.24851561/M_PI * 180.0f, 1.00092244/ M_PI * 180.0f,
|
||||||
|
5.8199234/ M_PI * 180.0f, 4.74536991/ M_PI * 180.0f}}; // 右右右右
|
||||||
|
c->motoroffset = motor_offset;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*对3508的速度环和6020的角速度以及位置环pid进行初始化*/
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
PID_Init(&c->pid.Wheel_DIR_omega[i], KPID_MODE_NO_D, target_freq, &c->param->pid.Wheel_DIR_Omega);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
PID_Init(&c->pid.Radder_DIR_omega[i], KPID_MODE_CALC_D, target_freq, &c->param->pid.Radder_DIR_Omega);
|
||||||
|
PID_Init(&c->pid.Radder_DIR_angle[i], KPID_MODE_CALC_D, target_freq, &c->param->pid.Radder_DIR_Angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
LowPassFilter2p_Init(&c->filled[0], target_freq, 20.0f); // vx
|
||||||
|
LowPassFilter2p_Init(&c->filled[1], target_freq, 20.0f); // vy
|
||||||
|
LowPassFilter2p_Init(&c->filled[2], target_freq, 20.0f); // vw
|
||||||
|
|
||||||
|
LowPassFilter2p_Init(&c->filled[3], target_freq, 20.0f); // 3508-1
|
||||||
|
LowPassFilter2p_Init(&c->filled[4], target_freq, 20.0f); // 3508-2
|
||||||
|
LowPassFilter2p_Init(&c->filled[5], target_freq, 20.0f); // 3508-3
|
||||||
|
LowPassFilter2p_Init(&c->filled[6], target_freq, 20.0f); // 3508-4
|
||||||
|
|
||||||
|
LowPassFilter2p_Init(&c->filled[7], target_freq, 20.0f); // 6020-1
|
||||||
|
LowPassFilter2p_Init(&c->filled[8], target_freq, 20.0f); // 6020-2
|
||||||
|
LowPassFilter2p_Init(&c->filled[9], target_freq, 20.0f); // 6020-3
|
||||||
|
LowPassFilter2p_Init(&c->filled[10], target_freq, 20.0f); // 6020-4
|
||||||
|
|
||||||
|
return CHASSIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief µç»úÊä³ö
|
|
||||||
* @param c µ×Å̽ṹÌåÖ¸Õë
|
|
||||||
*/
|
|
||||||
void Chassis_Output(Chassis_t *c) {
|
|
||||||
if (!c)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < c->num_wheel; i++) {
|
// 底盘解算
|
||||||
MOTOR_RM_t *rm = c->motors[i];
|
void Chassis_speed_calculate(Chassis_t *c, Chassis_CMD_t *c_cmd)
|
||||||
if (!rm) continue;
|
{
|
||||||
MOTOR_RM_SetOutput(&rm->param, c->out.motor[i]);
|
|
||||||
|
// RC模式下松开遥控器防止6020回到默认位置导致侧翻
|
||||||
|
if (c->mode == RC && fabs(c->move_vec.Vx) < 0.1 && fabs(c->move_vec.Vy) < 0.1 && fabs(c->move_vec.Vw) < 0.1)
|
||||||
|
{
|
||||||
|
// 如果之前不处于保持模式,则记录当前角度
|
||||||
|
if (!c->keeping_angle_flag)
|
||||||
|
{
|
||||||
|
c->keeping_angle_flag = 1; // 进入保持模式
|
||||||
|
}
|
||||||
|
// 使用保持的角度,而不是实时反馈值,速度为0
|
||||||
|
for (uint8_t i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
c->hopemotorout.Radder_DIR_Solving_1[i] = c->keep_angle[i];
|
||||||
|
c->hopemotorout.Wheel_DIR_Solving_1[i] = 0;
|
||||||
|
}
|
||||||
|
// c->hopemotorout.Radder_DIR_Solving_1[0] = 315;
|
||||||
|
// c->hopemotorout.Radder_DIR_Solving_1[1] = 45;
|
||||||
|
// c->hopemotorout.Radder_DIR_Solving_1[2] = 315;
|
||||||
|
// c->hopemotorout.Radder_DIR_Solving_1[3] = 45;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 如果有速度输入,则退出保持模式
|
||||||
|
c->keeping_angle_flag = 0;
|
||||||
|
// 让保持角度实时等于进入保持阈值前的最后一次角度值
|
||||||
|
for (uint8_t i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
c->keep_angle[i] = c->hopemotorout.Radder_DIR_Solving_1[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
//µ÷ÓÃctrl
|
switch (c->mode)
|
||||||
// for (uint8_t i = 0; i < c->num_wheel; i++) {
|
{
|
||||||
// MOTOR_RM_t *rm = c->motors[0];
|
case RC:
|
||||||
// if (rm) {
|
case CHASSIS_MODE_ROTOR:
|
||||||
// MOTOR_RM_Ctrl(&rm->param);
|
case CHASSIS_MODE_FOLLOW_GIMBAL:
|
||||||
// }
|
|
||||||
// }
|
// const double radians = atan(1.0f * 330 / 330);
|
||||||
|
|
||||||
|
c->hopemotorout.Wheel_DIR_Solving_1[0] = sqrt(
|
||||||
|
(c->move_vec.Vx + c->move_vec.Vw * sin(radians)) * (c->move_vec.Vx + c->move_vec.Vw * sin(radians)) + (c->move_vec.Vy + c->move_vec.Vw * cos(radians)) * (c->move_vec.Vy + c->move_vec.Vw * cos(radians)));
|
||||||
|
|
||||||
|
c->hopemotorout.Wheel_DIR_Solving_1[1] = sqrt(
|
||||||
|
(c->move_vec.Vx + c->move_vec.Vw * sin(radians)) * (c->move_vec.Vx + c->move_vec.Vw * sin(radians)) + (c->move_vec.Vy - c->move_vec.Vw * cos(radians)) * (c->move_vec.Vy - c->move_vec.Vw * cos(radians)));
|
||||||
|
|
||||||
|
c->hopemotorout.Wheel_DIR_Solving_1[2] = sqrt(
|
||||||
|
(c->move_vec.Vx - c->move_vec.Vw * sin(radians)) * (c->move_vec.Vx - c->move_vec.Vw * sin(radians)) + (c->move_vec.Vy - c->move_vec.Vw * cos(radians)) * (c->move_vec.Vy - c->move_vec.Vw * cos(radians)));
|
||||||
|
|
||||||
|
c->hopemotorout.Wheel_DIR_Solving_1[3] = sqrt(
|
||||||
|
(c->move_vec.Vx - c->move_vec.Vw * sin(radians)) * (c->move_vec.Vx - c->move_vec.Vw * sin(radians)) + (c->move_vec.Vy + c->move_vec.Vw * cos(radians)) * (c->move_vec.Vy + c->move_vec.Vw * cos(radians)));
|
||||||
|
|
||||||
|
c->hopemotorout.Radder_DIR_Solving_1[0] = atan2((c->move_vec.Vy + c->move_vec.Vw * cos(radians)),
|
||||||
|
(c->move_vec.Vx + c->move_vec.Vw * sin(radians))) *
|
||||||
|
(180.0f / M_PI);
|
||||||
|
c->hopemotorout.Radder_DIR_Solving_1[1] = atan2((c->move_vec.Vy - c->move_vec.Vw * cos(radians)),
|
||||||
|
(c->move_vec.Vx + c->move_vec.Vw * sin(radians))) *
|
||||||
|
(180.0f / M_PI);
|
||||||
|
c->hopemotorout.Radder_DIR_Solving_1[2] = atan2((c->move_vec.Vy - c->move_vec.Vw * cos(radians)),
|
||||||
|
(c->move_vec.Vx - c->move_vec.Vw * sin(radians))) *
|
||||||
|
(180.0f / M_PI);
|
||||||
|
c->hopemotorout.Radder_DIR_Solving_1[3] = atan2((c->move_vec.Vy + c->move_vec.Vw * cos(radians)),
|
||||||
|
(c->move_vec.Vx - c->move_vec.Vw * sin(radians))) *
|
||||||
|
(180.0f / M_PI);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CHASSIS_MODE_BREAK:
|
||||||
|
case STOP:
|
||||||
|
case CHASSIS_MODE_RELAX:
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
c->hopemotorout.Wheel_DIR_Solving_1[i] = 0.0f;
|
||||||
|
}
|
||||||
|
// c->hopemotorout.Radder_DIR_Solving_1[0] = 6.26554489/M_PI*180.0f;
|
||||||
|
// c->hopemotorout.Radder_DIR_Solving_1[1] = 2.1099906/M_PI*180.0f;
|
||||||
|
// c->hopemotorout.Radder_DIR_Solving_1[2] = 2.08391285/M_PI*180.0f;
|
||||||
|
// c->hopemotorout.Radder_DIR_Solving_1[3] = 5.26845694/M_PI*180.0f;
|
||||||
|
// c->hopemotorout.Radder_DIR_Solving_1[0] = 315;
|
||||||
|
// c->hopemotorout.Radder_DIR_Solving_1[1] = 45;
|
||||||
|
// c->hopemotorout.Radder_DIR_Solving_1[2] = 315;
|
||||||
|
// c->hopemotorout.Radder_DIR_Solving_1[3] = 45;
|
||||||
|
|
||||||
|
c->hopemotorout.Radder_DIR_Solving_1[0] = 0;
|
||||||
|
c->hopemotorout.Radder_DIR_Solving_1[1] = 0;
|
||||||
|
c->hopemotorout.Radder_DIR_Solving_1[2] = 0;
|
||||||
|
c->hopemotorout.Radder_DIR_Solving_1[3] = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
MOTOR_RM_t *rm = c->motors[0];
|
|
||||||
if (rm) {
|
|
||||||
MOTOR_RM_Ctrl(&rm->param);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// 角度归化到0°——360°
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (c->hopemotorout.Radder_DIR_Solving_1[i] < 0)
|
||||||
|
{
|
||||||
|
c->hopemotorout.Radder_DIR_Solving_1[i] += 360;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
float angle_error[4]; // 角度误差
|
||||||
|
angle_error[i] = c->hopemotorout.Radder_DIR_Solving_1[i] - c->feedback.motor_transformation.Radder_DIR_Angle[i];
|
||||||
|
// 误差角度归化到-180°——+180°
|
||||||
|
while (angle_error[i] > 180)
|
||||||
|
angle_error[i] -= 360;
|
||||||
|
while (angle_error[i] < -180)
|
||||||
|
angle_error[i] += 360;
|
||||||
|
/*这里发现如果下面的c->motorfeedback.rotor_angle6020[i]+angle_error[i]变为
|
||||||
|
c->hopemotorout.Radder_DIR_Solving_1[i]会导致6020出现故障*/
|
||||||
|
if (angle_error[i] > 90 && angle_error[i] <= 180)
|
||||||
|
{
|
||||||
|
c->hopemotorout.Wheel_DIR_Solving_2[i] = c->hopemotorout.Wheel_DIR_Solving_1[i];
|
||||||
|
c->hopemotorout.Radder_DIR_Solving_2[i] = c->feedback.motor_transformation.Radder_DIR_Angle[i] + angle_error[i] - 180;
|
||||||
|
}
|
||||||
|
else if (angle_error[i] < -90 && angle_error[i] >= -180)
|
||||||
|
{
|
||||||
|
c->hopemotorout.Wheel_DIR_Solving_2[i] = c->hopemotorout.Wheel_DIR_Solving_1[i];
|
||||||
|
c->hopemotorout.Radder_DIR_Solving_2[i] = c->feedback.motor_transformation.Radder_DIR_Angle[i] + angle_error[i] + 180;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c->hopemotorout.Wheel_DIR_Solving_2[i] = -c->hopemotorout.Wheel_DIR_Solving_1[i];
|
||||||
|
c->hopemotorout.Radder_DIR_Solving_2[i] = c->feedback.motor_transformation.Radder_DIR_Angle[i] + angle_error[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* @brief ÖØÖõ×ÅÌÊä³ö
|
更新底盘电机反馈,并且进行归一化处理,但是这里的归一化是我自己测的电机最大转速
|
||||||
* @param c µ×Å̽ṹÌåÖ¸Õë
|
近似于一进行处理,并不是准确的-1到1
|
||||||
*/
|
*/
|
||||||
void Chassis_ResetOutput(Chassis_t *c) {
|
|
||||||
if (!c) return;
|
int8_t Chassis_update(Chassis_t *c)
|
||||||
for (uint8_t i = 0; i < c->num_wheel; i++) {
|
{
|
||||||
MOTOR_RM_t *m = c->motors[i];
|
if (c == NULL)
|
||||||
if (m) {
|
{
|
||||||
MOTOR_RM_Relax(&(m->param));
|
return CHASSIS_ERR_NULL; // 参数错误
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
MOTOR_RM_t *Wheel_DIR_MOTOR[4];
|
||||||
|
MOTOR_RM_t *Radder_DIR_MOTOR[4];
|
||||||
|
/*更新电机反馈*/
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
/* 轮向电机更新 */
|
||||||
|
MOTOR_RM_Update(&(c->param->motor.Wheel_DIR[i]));
|
||||||
|
Wheel_DIR_MOTOR[i]= MOTOR_RM_GetMotor(&(c->param->motor.Wheel_DIR[i]));
|
||||||
|
c->feedback.motor.Wheel_DIR[i] = Wheel_DIR_MOTOR[i]->feedback;
|
||||||
|
|
||||||
|
/* 舵向电机 */
|
||||||
|
MOTOR_RM_Update(&(c->param->motor.Radder_DIR[i]));
|
||||||
|
Radder_DIR_MOTOR[i]= MOTOR_RM_GetMotor(&(c->param->motor.Radder_DIR[i]));
|
||||||
|
c->feedback.motor.Radder_DIR[i] = Radder_DIR_MOTOR[i]->feedback;
|
||||||
|
|
||||||
|
|
||||||
|
/* 单位转换 */
|
||||||
|
c->feedback.motor_transformation.Radder_DIR_Angle[i]=c->feedback.motor.Radder_DIR[i].rotor_abs_angle/ M_PI * 180.0f;
|
||||||
|
c->feedback.motor_transformation.Radder_DIR_Omega[i]= c->feedback.motor.Radder_DIR[i].rotor_speed/320;
|
||||||
|
c->feedback.motor_transformation.Wheel_DIR_Omega[i]= c->feedback.motor.Wheel_DIR[i].rotor_speed/10000;
|
||||||
|
c->feedback.motor_transformation.Radder_DIR_Angle[i] = fmod(c->feedback.motor_transformation.Radder_DIR_Angle[i] - c->motoroffset.MOTOR_OFFSET[i], 360.0);
|
||||||
|
|
||||||
|
if (c->feedback.motor_transformation.Radder_DIR_Angle[i] < 0)
|
||||||
|
{
|
||||||
|
c->feedback.motor_transformation.Radder_DIR_Angle[i] += 360;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return CHASSIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 防止侧翻
|
||||||
|
/*具体开始上车实验之后在进行编写修改,先暂时不使用*/
|
||||||
|
void ChassisrolPrevent(Chassis_t *c)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t Chassis_Control(Chassis_t *c, Chassis_CMD_t *c_cmd,uint32_t now)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (c == NULL || c_cmd == NULL)
|
||||||
|
{
|
||||||
|
return CHASSIS_ERR_NULL; // 参数错误
|
||||||
|
}
|
||||||
|
|
||||||
|
// c->dt = (BSP_TIME_Get_us() - c->last_wakeup) / 1000000.0f; /* 计算两次调用的时间间隔,单位秒 */
|
||||||
|
// c->last_wakeup = BSP_TIME_Get_us();
|
||||||
|
c->dt = (float)(now - c->last_wakeup) / 1000.0f; /* 计算两次调用的时间间隔,单位秒 */
|
||||||
|
c->last_wakeup = now;
|
||||||
|
|
||||||
|
/*设置底盘模式*/
|
||||||
|
if (Chassis_SetMode(c, c_cmd->mode,now) != CHASSIS_OK)
|
||||||
|
{
|
||||||
|
return CHASSIS_ERR_MODE; /* 设置模式失败 */
|
||||||
|
}
|
||||||
|
|
||||||
|
float beta;
|
||||||
|
|
||||||
|
/*根据底盘模式进行不同的控制*/
|
||||||
|
switch (c->mode)
|
||||||
|
{
|
||||||
|
case CHASSIS_MODE_BREAK:
|
||||||
|
case CHASSIS_MODE_RELAX:
|
||||||
|
case STOP:
|
||||||
|
// 停止模式
|
||||||
|
c->move_vec.Vx = 0.0f;
|
||||||
|
c->move_vec.Vy = 0.0f;
|
||||||
|
c->move_vec.Vw = 0.0f;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RC:
|
||||||
|
// 遥控模式
|
||||||
|
// c->move_vec.Vx = c_cmd->Vx * c_cmd->throttle * 1000.0f;
|
||||||
|
// c->move_vec.Vy = c_cmd->Vy * c_cmd->throttle * 1000.0f;
|
||||||
|
|
||||||
|
c->move_vec.Vx = c_cmd->Vx * c_cmd->throttle;
|
||||||
|
c->move_vec.Vy = c_cmd->Vy * c_cmd->throttle;
|
||||||
|
c->move_vec.Vw = c_cmd->Vw * c_cmd->throttle;
|
||||||
|
c->move_vec.mul = c_cmd->throttle;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CHASSIS_MODE_ROTOR:
|
||||||
|
// 小陀螺模式
|
||||||
|
|
||||||
|
beta = (c->feedback.motor.gimbal_yaw.rotor_abs_angle / 180.0f * M_PI) - c->mech_zero; // 云台当前角度转弧度
|
||||||
|
float cos_beta = cosf(beta);
|
||||||
|
float sin_beta = sinf(beta);
|
||||||
|
|
||||||
|
c->move_vec.Vx =cos_beta * c_cmd->x_l - sin_beta * c_cmd->y_l;
|
||||||
|
c->move_vec.Vy =sin_beta* c_cmd->x_l + cos_beta * c_cmd->y_l;
|
||||||
|
c->move_vec.Vw =c->wz_multi* Chassis_CalcWz(CHASSIS_ROTOR_WZ_MIN,CHASSIS_ROTOR_WZ_MAX, now);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CHASSIS_MODE_FOLLOW_GIMBAL:
|
||||||
|
// 跟随云台模式
|
||||||
|
c->move_vec.Vx =-c_cmd->y_l;
|
||||||
|
c->move_vec.Vy =-c_cmd->x_l;
|
||||||
|
c->move_vec.Vw = PID_Calc(&c->pid.chassis_follow_gimbal_pid, 2.06f ,c->feedback.motor.gimbal_yaw.rotor_abs_angle, 0.0f, c->dt);
|
||||||
|
|
||||||
|
// c->move_vec.Vw = -PID_Calc(&c->pid.chassis_follow_gimbal_pid, c->motorfeedback.gimbal_yaw_encoder-2.07694483f ,c->motorfeedback.gimbal_yaw_encoder, 0.0f, c->dt);
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
return CHASSIS_ERR_MODE; /* 未知模式 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*给输出的Vx,Vy,Vw进行滤波*/
|
||||||
|
c->move_vec.Vx = LowPassFilter2p_Apply(&c->filled[0], c->move_vec.Vx);
|
||||||
|
c->move_vec.Vy = LowPassFilter2p_Apply(&c->filled[1], c->move_vec.Vy);
|
||||||
|
c->move_vec.Vw = LowPassFilter2p_Apply(&c->filled[2], c->move_vec.Vw);
|
||||||
|
|
||||||
|
Chassis_speed_calculate(c, c_cmd);
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
float chassis6020_detangle[4]; // 6020解算出的角度
|
||||||
|
c->hopemotorout.Radder_DIR_target[i] = c->hopemotorout.Radder_DIR_Solving_2[i];
|
||||||
|
chassis6020_detangle[i] = PID_Calc(&(c->pid.Radder_DIR_angle[i]), c->hopemotorout.Radder_DIR_target[i],
|
||||||
|
c->feedback.motor_transformation.Radder_DIR_Angle[i], 0.0f, c->dt);
|
||||||
|
// c->final_out.final_6020out[i] = chassis6020_detangle[i] ; //单环控制就用这个
|
||||||
|
c->chassis6020_detangle[i]=chassis6020_detangle[i];
|
||||||
|
c->final_out.final_Radder_DIR[i] = PID_Calc(&(c->pid.Radder_DIR_omega[i]), chassis6020_detangle[i],
|
||||||
|
c->feedback.motor_transformation.Radder_DIR_Omega[i], 0.0f, c->dt);
|
||||||
|
|
||||||
|
c->out.Radder_DIR[i] = LowPassFilter2p_Apply(&c->filled[7+i], c->final_out.final_Radder_DIR[i]);
|
||||||
|
c->hopemotorout.Wheel_DIR_target[i] = c->hopemotorout.Wheel_DIR_Solving_2[i];
|
||||||
|
c->final_out.final_Wheel_DIR[i] = PID_Calc(&(c->pid.Wheel_DIR_omega[i]), c->hopemotorout.Wheel_DIR_target[i],
|
||||||
|
c->feedback.motor_transformation.Wheel_DIR_Omega[i], 0.0f, c->dt);
|
||||||
|
c->out.Wheel_DIR[i] = LowPassFilter2p_Apply(&c->filled[3+i], c->final_out.final_Wheel_DIR[i]);
|
||||||
|
|
||||||
|
}
|
||||||
|
return CHASSIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*电机输出设定和发送*/
|
||||||
|
void Chassis_Setoutput(Chassis_t *c)
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
|
MOTOR_RM_SetOutput(&(c->param->motor.Wheel_DIR[i]), c->out.Wheel_DIR[i]);
|
||||||
|
MOTOR_RM_SetOutput(&(c->param->motor.Radder_DIR[i]), c->out.Radder_DIR[i]);
|
||||||
|
}
|
||||||
|
MOTOR_RM_Ctrl(&(c->param->motor.Wheel_DIR[0]));
|
||||||
|
MOTOR_RM_Ctrl(&(c->param->motor.Radder_DIR[0]));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,239 +1,240 @@
|
|||||||
/*
|
|
||||||
µ×ÅÌÄ£×é
|
|
||||||
*/
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C"
|
||||||
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Includes ----------------------------------------------------------------- */
|
#include "struct_typedef.h"
|
||||||
#include <cmsis_os2.h>
|
|
||||||
#include "bsp/can.h"
|
|
||||||
#include "component/filter.h"
|
#include "component/filter.h"
|
||||||
#include "component/mixer.h"
|
|
||||||
#include "component/pid.h"
|
#include "component/pid.h"
|
||||||
#include "component/ahrs.h"
|
#include "component/ahrs.h"
|
||||||
|
//#include "device/buzzer.h"
|
||||||
|
#include "component/user_math.h"
|
||||||
|
#include "component/filter.h"
|
||||||
#include "device/motor_rm.h"
|
#include "device/motor_rm.h"
|
||||||
/* Exported constants ------------------------------------------------------- */
|
|
||||||
#define CHASSIS_OK (0) /* ÔËÐÐÕý³£ */
|
|
||||||
#define CHASSIS_ERR (-1) /* ÔËÐÐʱ³öÏÖÁËһЩС´íÎó */
|
|
||||||
#define CHASSIS_ERR_NULL (-2) /* ÔËÐÐʱ·¢ÏÖNULLÖ¸Õë */
|
|
||||||
#define CHASSIS_ERR_MODE (-3) /* ÔËÐÐʱ³öÅäÖÃÁË´íÎóµÄChassisMode_t */
|
|
||||||
#define CHASSIS_ERR_TYPE (-4) /* ÔËÐÐʱ³öÅäÖÃÁË´íÎóµÄChassis_Type_t */
|
|
||||||
|
|
||||||
#define MAX_MOTOR_CURRENT 20.0f
|
typedef struct {
|
||||||
/* µ×ÅÌ¿ØÖÆÄ£Ê½ */
|
float max_velocity;
|
||||||
typedef enum {
|
float acceleration;
|
||||||
CHASSIS_MODE_RELAX, /* ·ÅËÉģʽ,µç»ú²»Êä³ö¡£Ò»°ãÇé¿öµ×Å̳õʼ»¯Ö®ºóµÄģʽ */
|
float deceleration;
|
||||||
CHASSIS_MODE_BREAK, /* ɲ³µÄ£Ê½£¬µç»ú±Õ»·¿ØÖƾ²Ö¹¡£ÓÃÓÚ»úÆ÷ÈËֹͣ״̬ */
|
} TrapezoidalProfile;
|
||||||
CHASSIS_MODE_FOLLOW_GIMBAL, /* ͨ¹ý±Õ»·¿ØÖÆÊ¹³µÍ··½Ïò¸úËæÔÆÌ¨ */
|
|
||||||
CHASSIS_MODE_FOLLOW_GIMBAL_35, /* ͨ¹ý±Õ»·¿ØÖÆÊ¹³µÍ··½Ïò35¡ã¸úËæÔÆÌ¨ */
|
#define CHASSIS_OK (0)
|
||||||
CHASSIS_MODE_ROTOR, /* СÍÓÂÝģʽ£¬Í¨¹ý±Õ»·¿ØÖÆÊ¹µ×Å̲»Í£Ðýת */
|
#define CHASSIS_ERR (-1)
|
||||||
CHASSIS_MODE_INDEPENDENT, /*¶ÀÁ¢Ä£Ê½¡£µ×ÅÌÔËÐв»ÊÜÔÆÌ¨Ó°Ïì */
|
#define CHASSIS_ERR_NULL (-2)
|
||||||
CHASSIS_MODE_OPEN, /* ¿ª»·Ä£Ê½¡£µ×ÅÌÔËÐв»ÊÜPID¿ØÖÆ£¬Ö±½ÓÊä³öµ½µç»ú */
|
#define CHASSIS_ERR_MODE (-3) /*CMD_ChassisMode_t */
|
||||||
|
#define CHASSIS_ERR_TYPE (-4) /*Chassis_Type_t */
|
||||||
|
|
||||||
|
|
||||||
|
// 纵向/横向
|
||||||
|
#define radians atan(1.0f * 390 /390) // 角度制
|
||||||
|
|
||||||
|
|
||||||
|
/*底盘姿态模式*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
STOP_MODE,/* 急停模式 */
|
||||||
|
EXPAND_MODE,/* 展开模式 */
|
||||||
|
REDUCE_MODE,/* 收缩模式 */
|
||||||
|
} CHASSIS_ATTITUDE_MODE_t;
|
||||||
|
|
||||||
|
/*底盘状态*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
STOP_STATE,/* 急停状态 */
|
||||||
|
EXPAND_STATE,/* 展开状态 */
|
||||||
|
REDUCE_STATE,/* 收缩状态 */
|
||||||
|
} CHASSIS_STATE_t;
|
||||||
|
|
||||||
|
/*底盘模式*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
STOP, // 底盘平行
|
||||||
|
RC, // 遥控模式
|
||||||
|
CHASSIS_MODE_BREAK, /* 刹车模式,电机闭环控制保持静止。用于机器人停止状态 */
|
||||||
|
CHASSIS_MODE_RELAX, /* 放松模式,电机不输出。一般情况底盘初始化之后的模式 */
|
||||||
|
CHASSIS_MODE_FOLLOW_GIMBAL, /* 通过闭环控制使车头方向跟随云台 */
|
||||||
|
CHASSIS_MODE_ROTOR, /* 小陀螺模式,通过闭环控制使底盘不停旋转 */
|
||||||
|
|
||||||
} Chassis_Mode_t;
|
} Chassis_Mode_t;
|
||||||
|
|
||||||
/* СÍÓÂÝת¶¯Ä£Ê½ */
|
typedef struct
|
||||||
typedef enum {
|
{
|
||||||
ROTOR_MODE_CW, /* ˳ʱÕëת¶¯ */
|
int cmd_power_on_safe; // 上电安全标志
|
||||||
ROTOR_MODE_CCW, /* ÄæÊ±Õëת¶¯ */
|
Chassis_Mode_t mode;
|
||||||
ROTOR_MODE_RAND, /* Ëæ»úת¶¯ */
|
CHASSIS_ATTITUDE_MODE_t attitude_mode;
|
||||||
} Chassis_RotorMode_t;
|
// 遥控器输出值
|
||||||
|
fp32 Vx;
|
||||||
|
fp32 Vy;
|
||||||
|
fp32 Vw;
|
||||||
|
fp32 throttle;
|
||||||
|
|
||||||
/* µ×ÅÌ¿ØÖÆÃüÁî */
|
fp32 x_l;
|
||||||
typedef struct {
|
fp32 y_l;
|
||||||
Chassis_Mode_t mode; /* µ×ÅÌÔËÐÐģʽ */
|
|
||||||
Chassis_RotorMode_t mode_rotor; /* СÍÓÂÝת¶¯Ä£Ê½ */
|
|
||||||
MoveVector_t ctrl_vec; /* µ×ÅÌ¿ØÖÆÏòÁ¿ */
|
|
||||||
} Chassis_CMD_t;
|
} Chassis_CMD_t;
|
||||||
|
|
||||||
/* ÏÞλ */
|
// 四个舵轮的安装误差
|
||||||
typedef struct {
|
typedef struct
|
||||||
float max;
|
{
|
||||||
float min;
|
fp32 MOTOR_OFFSET[4];
|
||||||
} Chassis_Limit_t;
|
} MotorOffset_t;
|
||||||
|
|
||||||
/* µ×ÅÌÀàÐÍ£¨µ×Å̵ÄÎïÀíÉè¼Æ£© */
|
typedef struct
|
||||||
typedef enum {
|
{
|
||||||
CHASSIS_TYPE_MECANUM, /* Âó¿ËÄÉÄ·ÂÖ */
|
fp32 TELESCOPE_MOTOR_OFFSET[2];
|
||||||
CHASSIS_TYPE_PARLFIX4, /* ƽÐаڷŵÄËĸöÇý¶¯ÂÖ */
|
} TelescopeMotorOffset_t;
|
||||||
CHASSIS_TYPE_PARLFIX2, /* ƽÐаڷŵÄÁ½¸öÇý¶¯ÂÖ */
|
|
||||||
CHASSIS_TYPE_OMNI_CROSS, /* ²æÐͰڷŵÄËĸöÈ«ÏòÂÖ */
|
typedef struct
|
||||||
CHASSIS_TYPE_OMNI_PLUS, /* Ê®×ÖÐͰÚÉèµÄËĸöÈ«ÏòÂÖ */
|
{
|
||||||
CHASSIS_TYPE_DRONE, /* ÎÞÈË»úµ×ÅÌ */
|
/*可通过该枚举类型来决定Imu的数据量纲*/
|
||||||
CHASSIS_TYPE_SINGLE, /* µ¥¸öĦ²ÁÂÖ */
|
enum
|
||||||
} Chassis_Type_t;
|
{
|
||||||
|
IMU_DEGREE, // 角度值(0-360)
|
||||||
|
IMU_RADIAN // 弧度制(0-2pi)
|
||||||
|
} angle_mode;
|
||||||
|
|
||||||
|
// AHRS_Eulr_t imu_eulr; // 解算后存放欧拉角(弧度制)
|
||||||
|
} ChassisImu_t;
|
||||||
|
|
||||||
|
/*底盘参数结构体*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
/* µ×Å̲ÎÊý½á¹¹Ìå,ALL³õʼ»¯²ÎÊý */
|
|
||||||
typedef struct {
|
|
||||||
MOTOR_RM_Param_t motor_param[4];
|
|
||||||
struct {
|
|
||||||
KPID_Params_t motor_pid_param; /* µ×Å̵ç»úPID²ÎÊý */
|
|
||||||
KPID_Params_t follow_pid_param; /* ¸úËæÔÆÌ¨PID²ÎÊý */
|
|
||||||
} pid;
|
|
||||||
Chassis_Type_t type; /* µ×ÅÌÀàÐÍ£¬µ×Å̵ĻúеÉè¼ÆºÍÂÖ×ÓÑ¡ÐÍ */
|
|
||||||
|
|
||||||
/* µÍͨÂ˲¨Æ÷½ØÖÁƵÂÊ*/
|
|
||||||
struct {
|
|
||||||
float in; /* ÊäÈë */
|
|
||||||
float out; /* Êä³ö */
|
|
||||||
} low_pass_cutoff_freq;
|
|
||||||
|
|
||||||
/* µç»ú·´×°£¬Ó¦¸ÃºÍÔÆÌ¨ÉèÖÃÏàͬ*/
|
|
||||||
struct {
|
|
||||||
bool yaw;
|
|
||||||
} reverse;
|
|
||||||
struct {
|
|
||||||
float max_vx, max_vy, max_wz;
|
|
||||||
float max_current;
|
|
||||||
} limit;
|
|
||||||
} Chassis_Params_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
AHRS_Gyro_t gyro;
|
|
||||||
AHRS_Eulr_t eulr;
|
|
||||||
} Chassis_IMU_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
MOTOR_Feedback_t motor[4]; // Ëĸö 3508µç»ú ·´À¡
|
|
||||||
float encoder_gimbalYawMotor;
|
|
||||||
} Chassis_Feedback_t;
|
|
||||||
|
|
||||||
/* µ×ÅÌÊä³ö½á¹¹Ìå*/
|
|
||||||
typedef struct {
|
|
||||||
float motor[4];
|
|
||||||
} Chassis_Output_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ÔËÐеÄÖ÷½á¹¹Ìå£þ
|
|
||||||
* °üº¬³õʼ»¯²ÎÊý,Öмä±äÁ¿,Êä³ö±äÁ¿
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
uint64_t last_wakeup;
|
|
||||||
float dt;
|
|
||||||
|
|
||||||
Chassis_Params_t *param; /* µ×Å̲ÎÊý,ÓÃChassis_InitÉ趨 */
|
|
||||||
|
|
||||||
/* Ä£¿éͨÓà */
|
|
||||||
Chassis_Mode_t mode; /* µ×ÅÌģʽ */
|
|
||||||
|
|
||||||
|
|
||||||
/* µ×ÅÌÉè¼Æ */
|
struct{
|
||||||
int8_t num_wheel; /* µ×ÅÌÂÖ×ÓÊýÁ¿ */
|
/*该部分决定PID的参数整定在config中修改*/
|
||||||
Mixer_t mixer; /* »ìºÏÆ÷,ÒÆ¶¯ÏòÁ¿->µç»úÄ¿±êÖµ */
|
KPID_Params_t Radder_DIR_Omega;
|
||||||
MoveVector_t move_vec; /* µ×ÅÌʵ¼ÊµÄÔ˶¯ÏòÁ¿ */
|
KPID_Params_t Radder_DIR_Angle;
|
||||||
MOTOR_RM_t *motors[4];/*Ö¸Ïòµ×ÅÌÿ¸öµç»ú²ÎÊý*/
|
KPID_Params_t Wheel_DIR_Omega;
|
||||||
float mech_zero;
|
KPID_Params_t chassis_follow_gimbal;
|
||||||
float wz_multi; /* СÍÓÂÝÐýתģʽ */
|
}pid;
|
||||||
|
|
||||||
/* PID¼ÆËãÄ¿±êÖµ */
|
struct{
|
||||||
struct {
|
MOTOR_RM_Param_t Wheel_DIR[4]; // 四个轮向电机
|
||||||
float motor_rpm[4]; /* µç»úתËٵĶ¯Ì¬Êý×é,µ¥Î»:RPM */
|
MOTOR_RM_Param_t Radder_DIR[4]; // 四个舵向电机
|
||||||
} setpoint;
|
MOTOR_RM_Param_t chassis_follow_gimbal; // 底盘跟随云台
|
||||||
|
|
||||||
/* ·´À¡¿ØÖÆÓõÄPID */
|
}motor;
|
||||||
struct {
|
float mech_zero;/*云台6020的机械中点*/
|
||||||
KPID_t motor[4]; /* ¿ØÖÆÂÖ×Óµç»úÓõÄPIDµÄ¶¯Ì¬Êý×é */
|
float travel ;/*云台6020的机械行程*/
|
||||||
KPID_t follow; /* ¸úËæÔÆÌ¨ÓõÄPID */
|
float mech_zero_4310;/*云台4310的机械中点*/
|
||||||
} pid;
|
} Chassis_Param_t;
|
||||||
|
|
||||||
struct {
|
typedef struct
|
||||||
Chassis_Limit_t vx, vy, wz;
|
{
|
||||||
} limit;
|
fp32 Vx;
|
||||||
|
fp32 Vy;
|
||||||
|
fp32 Vw;
|
||||||
|
fp32 mul; // 油门倍率
|
||||||
|
} ChassisMove_Vec;
|
||||||
|
|
||||||
/* Â˲¨Æ÷ */
|
typedef struct
|
||||||
struct {
|
{
|
||||||
LowPassFilter2p_t in[4]; /* ·´À¡ÖµÂ˲¨Æ÷ */
|
float Wheel_DIR[4];
|
||||||
LowPassFilter2p_t out[4]; /* Êä³öÖµÂ˲¨Æ÷ */
|
float Radder_DIR[4];
|
||||||
} filter;
|
} Chassis_out_t;
|
||||||
|
|
||||||
Chassis_Output_t out; /* µç»úÊä³ö */
|
typedef struct
|
||||||
Chassis_Feedback_t feedback;
|
{
|
||||||
//float out_motor[4];
|
|
||||||
} Chassis_t;
|
|
||||||
|
|
||||||
/* Exported functions prototypes -------------------------------------------- */
|
uint32_t last_wakeup;
|
||||||
|
float dt;
|
||||||
|
float chassis6020_detangle[4];
|
||||||
|
Chassis_Mode_t mode;
|
||||||
|
ChassisMove_Vec move_vec; // 最终输入速度
|
||||||
|
TrapezoidalProfile telescope_profile;
|
||||||
|
/* 设立角度和跟随角度 */
|
||||||
|
float Set_TelescopeAngle;
|
||||||
|
float Last_Set_TelescopeAngle;
|
||||||
|
float Follow_TelescopeAngle;
|
||||||
|
float feedfrward;
|
||||||
|
float Telescope_err;
|
||||||
|
/*期望的底盘输出值(此处为舵轮解算出的各个电机的期望输出值)ֵ*/
|
||||||
|
struct{
|
||||||
|
uint32_t last_wakeup;
|
||||||
|
float dt;
|
||||||
|
}accl_time;
|
||||||
|
|
||||||
/**
|
struct
|
||||||
* \brief µ×Å̳õʼ»¯
|
{
|
||||||
*
|
fp32 Wheel_DIR_Solving_1[4];
|
||||||
* \param c °üº¬µ×ÅÌÊý¾ÝµÄ½á¹¹Ìå
|
fp32 Wheel_DIR_Solving_2[4];
|
||||||
* \param param °üº¬µ×Å̲ÎÊýµÄ½á¹¹ÌåÖ¸Õë
|
fp32 Radder_DIR_Solving_1[4];
|
||||||
* \param target_freq ÈÎÎñÔ¤ÆÚµÄÔËÐÐÆµÂÊ
|
fp32 Radder_DIR_Solving_2[4];
|
||||||
*
|
// fp32 rotor6020_elur_yaw;
|
||||||
* \return ÔËÐнá¹û
|
|
||||||
*/
|
|
||||||
int8_t Chassis_Init(Chassis_t *c, const Chassis_Params_t *param,
|
|
||||||
float target_freq);
|
|
||||||
|
|
||||||
/**
|
fp32 Radder_DIR_target[4];
|
||||||
* \brief ¸üе×ÅÌ·´À¡ÐÅÏ¢
|
fp32 Wheel_DIR_target[4];
|
||||||
*
|
|
||||||
* \param c °üº¬µ×ÅÌÊý¾ÝµÄ½á¹¹Ìå
|
|
||||||
* \param can CANÉ豸½á¹¹Ìå
|
|
||||||
*
|
|
||||||
* \return ÔËÐнá¹û
|
|
||||||
*/
|
|
||||||
int8_t Chassis_UpdateFeedback(Chassis_t *c);
|
|
||||||
|
|
||||||
/**
|
} hopemotorout;
|
||||||
* \brief ÔËÐе×ÅÌ¿ØÖÆÂß¼
|
|
||||||
*
|
struct
|
||||||
* \param c °üº¬µ×ÅÌÊý¾ÝµÄ½á¹¹Ìå
|
{
|
||||||
* \param c_cmd µ×ÅÌ¿ØÖÆÖ¸Áî
|
fp32 final_Telescope;
|
||||||
* \param dt_sec Á½´Îµ÷ÓõÄʱ¼ä¼ä¸ô
|
fp32 final_Radder_DIR[4];
|
||||||
*
|
fp32 final_Wheel_DIR[4];
|
||||||
* \return ÔËÐнá¹û
|
} final_out;
|
||||||
*/
|
/* 原始数据 */
|
||||||
int8_t Chassis_Control(Chassis_t *c, const Chassis_CMD_t *c_cmd,
|
struct
|
||||||
uint32_t now);
|
{
|
||||||
|
struct{
|
||||||
|
|
||||||
|
MOTOR_Feedback_t Wheel_DIR[4]; // 四个轮向电机
|
||||||
|
MOTOR_Feedback_t Radder_DIR[4];
|
||||||
|
MOTOR_Feedback_t gimbal_yaw;
|
||||||
|
}motor;
|
||||||
|
/* 转化数据 */
|
||||||
|
struct{
|
||||||
|
|
||||||
|
float Radder_DIR_Angle[4];
|
||||||
|
float Radder_DIR_Omega[4];
|
||||||
|
float Wheel_DIR_Angle[4];
|
||||||
|
float Wheel_DIR_Omega[4];
|
||||||
|
}motor_transformation;
|
||||||
|
|
||||||
|
} feedback;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
KPID_t Radder_DIR_angle[4];
|
||||||
|
KPID_t Radder_DIR_omega[4];
|
||||||
|
KPID_t Wheel_DIR_omega[4];
|
||||||
|
KPID_t chassis_follow_gimbal_pid;
|
||||||
|
} pid;
|
||||||
|
|
||||||
|
uint8_t keeping_angle_flag; // 是否处于保持角度模式
|
||||||
|
|
||||||
|
// AHRS_Eulr_t set_point; // 底盘纠正目标角
|
||||||
|
// fp32 angle_current; // 当前角度
|
||||||
|
// fp32 angle_piancha; // 偏差角度
|
||||||
|
// fp32 yaw_out; // 角度pid输出值
|
||||||
|
|
||||||
|
ChassisImu_t pos088; // 088的实时姿态
|
||||||
|
MotorOffset_t motoroffset; // 5065校准数据
|
||||||
|
TelescopeMotorOffset_t telescope_motor_offset;
|
||||||
|
|
||||||
|
|
||||||
/**
|
Chassis_Param_t *param; // 一些固定的参数
|
||||||
* \brief ¸´ÖƵ×ÅÌÊä³öÖµ
|
LowPassFilter2p_t filled[11]; // 低通滤波器
|
||||||
*
|
LowPassFilter2p_t accl_filled[2]; // 加速度滤波器
|
||||||
* \param s °üº¬µ×ÅÌÊý¾ÝµÄ½á¹¹Ìå
|
float keep_angle[4]; // 保持的 舵向 角度
|
||||||
* \param out CANÉ豸µ×ÅÌÊä³ö½á¹¹Ìå
|
|
||||||
*/
|
|
||||||
void Chassis_Output(Chassis_t *c);
|
|
||||||
|
|
||||||
/**
|
Chassis_out_t out;
|
||||||
* \brief Çå¿ÕChassisÊä³öÊý¾Ý
|
|
||||||
*
|
float wz_multi; /* 小陀螺模式旋转方向 */
|
||||||
* \param out CANÉ豸µ×ÅÌÊä³ö½á¹¹Ìå
|
float mech_zero;/*云台6020的机械中点*/
|
||||||
*/
|
float travel ;/*云台6020的机械行程*/
|
||||||
void Chassis_ResetOutput(Chassis_t *c);
|
// float mech_zero_4310;/*云台4310的机械中点*/
|
||||||
|
} Chassis_t;
|
||||||
|
|
||||||
void Chassis_Power_Control(Chassis_t *c,float max_power);
|
|
||||||
/**
|
|
||||||
* @brief µ×Å̹¦ÂÊÏÞÖÆ
|
|
||||||
*
|
|
||||||
* @param c µ×ÅÌÊý¾Ý
|
|
||||||
* @param cap µçÈÝÊý¾Ý
|
|
||||||
* @param ref ²ÃÅÐϵͳÊý¾Ý
|
|
||||||
* @return º¯ÊýÔËÐнá¹û
|
|
||||||
*/
|
|
||||||
//»¹Ã»ÓмÓÈ룬waiting¡£¡£¡£¡£¡£¡£int8_t Chassis_PowerLimit(Chassis_t *c, const CAN_Capacitor_t *cap,
|
|
||||||
// const Referee_ForChassis_t *ref);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief µ¼³öµ×ÅÌÊý¾Ý
|
|
||||||
*
|
|
||||||
* @param chassis µ×ÅÌÊý¾Ý½á¹¹Ìå
|
|
||||||
* @param ui UIÊý¾Ý½á¹¹Ìå
|
|
||||||
*/
|
|
||||||
//void Chassis_DumpUI(const Chassis_t *c, Referee_ChassisUI_t *ui);
|
|
||||||
|
|
||||||
|
|
||||||
|
int8_t chassis_init(Chassis_t *c, Chassis_Param_t *param, float target_freq);
|
||||||
|
int8_t Chassis_update(Chassis_t *c);
|
||||||
|
int8_t Chassis_Control(Chassis_t *c, Chassis_CMD_t *c_cmd,uint32_t now);
|
||||||
|
void Chassis_Setoutput(Chassis_t *c);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -17,15 +17,16 @@ static void CMD_RC_BuildChassisCmd(CMD_t *ctx) {
|
|||||||
CMD_RCModeMap_t *map = &ctx->config->rc_mode_map;
|
CMD_RCModeMap_t *map = &ctx->config->rc_mode_map;
|
||||||
|
|
||||||
/* 根据左拨杆位置选择模式 */
|
/* 根据左拨杆位置选择模式 */
|
||||||
switch (ctx->input.rc.sw[0]) {
|
switch (ctx->input.rc.sw[1]) {
|
||||||
case CMD_SW_UP:
|
case CMD_SW_UP:
|
||||||
ctx->output.chassis.cmd.mode = map->sw_left_up;
|
ctx->output.chassis.cmd.mode = map->sw_left_up;
|
||||||
break;
|
break;
|
||||||
case CMD_SW_MID:
|
case CMD_SW_MID:
|
||||||
|
ctx->output.chassis.cmd.throttle = 1;
|
||||||
ctx->output.chassis.cmd.mode = map->sw_left_mid;
|
ctx->output.chassis.cmd.mode = map->sw_left_mid;
|
||||||
break;
|
break;
|
||||||
case CMD_SW_DOWN:
|
case CMD_SW_DOWN:
|
||||||
ctx->output.chassis.cmd.mode = map->sw_left_down;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ctx->output.chassis.cmd.mode = CHASSIS_MODE_RELAX;
|
ctx->output.chassis.cmd.mode = CHASSIS_MODE_RELAX;
|
||||||
@ -33,9 +34,9 @@ static void CMD_RC_BuildChassisCmd(CMD_t *ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 摇杆控制移动 */
|
/* 摇杆控制移动 */
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vx = ctx->input.rc.joy_right.x;
|
ctx->output.chassis.cmd.Vx =- ctx->input.rc.joy_right.y;
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vy = ctx->input.rc.joy_right.y;
|
ctx->output.chassis.cmd.Vy = -ctx->input.rc.joy_right.x;
|
||||||
ctx->output.chassis.cmd.ctrl_vec.wz = ctx->input.rc.joy_left.x;
|
|
||||||
}
|
}
|
||||||
#endif /* CMD_ENABLE_SRC_RC && CMD_ENABLE_MODULE_CHASSIS */
|
#endif /* CMD_ENABLE_SRC_RC && CMD_ENABLE_MODULE_CHASSIS */
|
||||||
|
|
||||||
@ -77,19 +78,19 @@ static void CMD_RC_BuildShootCmd(CMD_t *ctx) {
|
|||||||
|
|
||||||
/* 根据右拨杆控制射击 */
|
/* 根据右拨杆控制射击 */
|
||||||
switch (ctx->input.rc.sw[1]) {
|
switch (ctx->input.rc.sw[1]) {
|
||||||
case CMD_SW_DOWN:
|
// case CMD_SW_DOWN:
|
||||||
ctx->output.shoot.cmd.ready = true;
|
// ctx->output.shoot.cmd.ready = true;
|
||||||
ctx->output.shoot.cmd.firecmd = true;
|
// ctx->output.shoot.cmd.firecmd = true;
|
||||||
break;
|
// break;
|
||||||
case CMD_SW_MID:
|
// case CMD_SW_MID:
|
||||||
ctx->output.shoot.cmd.ready = true;
|
// ctx->output.shoot.cmd.ready = true;
|
||||||
ctx->output.shoot.cmd.firecmd = false;
|
// ctx->output.shoot.cmd.firecmd = false;
|
||||||
break;
|
// break;
|
||||||
case CMD_SW_UP:
|
// case CMD_SW_UP:
|
||||||
default:
|
// default:
|
||||||
ctx->output.shoot.cmd.ready = false;
|
// ctx->output.shoot.cmd.ready = false;
|
||||||
ctx->output.shoot.cmd.firecmd = false;
|
// ctx->output.shoot.cmd.firecmd = false;
|
||||||
break;
|
// break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* CMD_ENABLE_SRC_RC && CMD_ENABLE_MODULE_SHOOT */
|
#endif /* CMD_ENABLE_SRC_RC && CMD_ENABLE_MODULE_SHOOT */
|
||||||
@ -141,8 +142,7 @@ static void CMD_PC_BuildChassisCmd(CMD_t *ctx) {
|
|||||||
ctx->output.chassis.cmd.mode = CHASSIS_MODE_FOLLOW_GIMBAL;
|
ctx->output.chassis.cmd.mode = CHASSIS_MODE_FOLLOW_GIMBAL;
|
||||||
|
|
||||||
/* WASD控制移动 */
|
/* WASD控制移动 */
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vx = 0.0f;
|
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vy = 0.0f;
|
|
||||||
CMD_Behavior_ProcessAll(ctx, &ctx->input, &ctx->last_input, CMD_MODULE_CHASSIS);
|
CMD_Behavior_ProcessAll(ctx, &ctx->input, &ctx->last_input, CMD_MODULE_CHASSIS);
|
||||||
}
|
}
|
||||||
#endif /* CMD_ENABLE_SRC_PC && CMD_ENABLE_MODULE_CHASSIS */
|
#endif /* CMD_ENABLE_SRC_PC && CMD_ENABLE_MODULE_CHASSIS */
|
||||||
|
|||||||
@ -15,44 +15,44 @@
|
|||||||
/* 行为处理函数实现 */
|
/* 行为处理函数实现 */
|
||||||
int8_t CMD_Behavior_Handle_FORE(CMD_t *ctx) {
|
int8_t CMD_Behavior_Handle_FORE(CMD_t *ctx) {
|
||||||
#if CMD_ENABLE_MODULE_CHASSIS
|
#if CMD_ENABLE_MODULE_CHASSIS
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vy += ctx->config->sensitivity.move_sens;
|
ctx->output.chassis.cmd.Vy += ctx->config->sensitivity.move_sens;
|
||||||
#endif
|
#endif
|
||||||
return CMD_OK;
|
return CMD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t CMD_Behavior_Handle_BACK(CMD_t *ctx) {
|
int8_t CMD_Behavior_Handle_BACK(CMD_t *ctx) {
|
||||||
#if CMD_ENABLE_MODULE_CHASSIS
|
#if CMD_ENABLE_MODULE_CHASSIS
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vy -= ctx->config->sensitivity.move_sens;
|
ctx->output.chassis.cmd.Vy -= ctx->config->sensitivity.move_sens;
|
||||||
#endif
|
#endif
|
||||||
return CMD_OK;
|
return CMD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t CMD_Behavior_Handle_LEFT(CMD_t *ctx) {
|
int8_t CMD_Behavior_Handle_LEFT(CMD_t *ctx) {
|
||||||
#if CMD_ENABLE_MODULE_CHASSIS
|
#if CMD_ENABLE_MODULE_CHASSIS
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vx -= ctx->config->sensitivity.move_sens;
|
ctx->output.chassis.cmd.Vx -= ctx->config->sensitivity.move_sens;
|
||||||
#endif
|
#endif
|
||||||
return CMD_OK;
|
return CMD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t CMD_Behavior_Handle_RIGHT(CMD_t *ctx) {
|
int8_t CMD_Behavior_Handle_RIGHT(CMD_t *ctx) {
|
||||||
#if CMD_ENABLE_MODULE_CHASSIS
|
#if CMD_ENABLE_MODULE_CHASSIS
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vx += ctx->config->sensitivity.move_sens;
|
ctx->output.chassis.cmd.Vx += ctx->config->sensitivity.move_sens;
|
||||||
#endif
|
#endif
|
||||||
return CMD_OK;
|
return CMD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t CMD_Behavior_Handle_ACCELERATE(CMD_t *ctx) {
|
int8_t CMD_Behavior_Handle_ACCELERATE(CMD_t *ctx) {
|
||||||
#if CMD_ENABLE_MODULE_CHASSIS
|
#if CMD_ENABLE_MODULE_CHASSIS
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vx *= ctx->config->sensitivity.move_fast_mult;
|
ctx->output.chassis.cmd.Vx *= ctx->config->sensitivity.move_fast_mult;
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vy *= ctx->config->sensitivity.move_fast_mult;
|
ctx->output.chassis.cmd.Vy *= ctx->config->sensitivity.move_fast_mult;
|
||||||
#endif
|
#endif
|
||||||
return CMD_OK;
|
return CMD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t CMD_Behavior_Handle_DECELERATE(CMD_t *ctx) {
|
int8_t CMD_Behavior_Handle_DECELERATE(CMD_t *ctx) {
|
||||||
#if CMD_ENABLE_MODULE_CHASSIS
|
#if CMD_ENABLE_MODULE_CHASSIS
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vx *= ctx->config->sensitivity.move_slow_mult;
|
ctx->output.chassis.cmd.Vx *= ctx->config->sensitivity.move_slow_mult;
|
||||||
ctx->output.chassis.cmd.ctrl_vec.vy *= ctx->config->sensitivity.move_slow_mult;
|
ctx->output.chassis.cmd.Vy *= ctx->config->sensitivity.move_slow_mult;
|
||||||
#endif
|
#endif
|
||||||
return CMD_OK;
|
return CMD_OK;
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ int8_t CMD_Behavior_Handle_FIRE_MODE(CMD_t *ctx) {
|
|||||||
int8_t CMD_Behavior_Handle_ROTOR(CMD_t *ctx) {
|
int8_t CMD_Behavior_Handle_ROTOR(CMD_t *ctx) {
|
||||||
#if CMD_ENABLE_MODULE_CHASSIS
|
#if CMD_ENABLE_MODULE_CHASSIS
|
||||||
ctx->output.chassis.cmd.mode = CHASSIS_MODE_ROTOR;
|
ctx->output.chassis.cmd.mode = CHASSIS_MODE_ROTOR;
|
||||||
ctx->output.chassis.cmd.mode_rotor = ROTOR_MODE_RAND;
|
// ctx->output.chassis.cmd.mode_rotor = ROTOR_MODE_RAND;
|
||||||
#endif
|
#endif
|
||||||
#if CMD_ENABLE_MODULE_GIMBAL
|
#if CMD_ENABLE_MODULE_GIMBAL
|
||||||
ctx->output.gimbal.cmd.mode = GIMBAL_MODE_RELATIVE;
|
ctx->output.gimbal.cmd.mode = GIMBAL_MODE_RELATIVE;
|
||||||
|
|||||||
@ -19,81 +19,51 @@
|
|||||||
// theta(变量), d(mm), a(mm), alpha(rad), theta_offset(rad)
|
// theta(变量), d(mm), a(mm), alpha(rad), theta_offset(rad)
|
||||||
// 零位姿态: 机械臂竖直向上
|
// 零位姿态: 机械臂竖直向上
|
||||||
Config_RobotParam_t robot_config = {
|
Config_RobotParam_t robot_config = {
|
||||||
.chassis_param = {
|
.chassis_param={
|
||||||
/* DJI3508µç»ú*/
|
.pid={
|
||||||
.motor_param = {
|
.Radder_DIR_Omega={
|
||||||
{
|
.k=1.0f,
|
||||||
.can = BSP_CAN_1,
|
.p=0.5f,
|
||||||
.id = 0x201,
|
.i=0.15f,
|
||||||
.module = MOTOR_M3508,
|
.d=0.0f,
|
||||||
.reverse = false,
|
.i_limit=1.0f,
|
||||||
.gear = true
|
.out_limit=1.0f,
|
||||||
},
|
.d_cutoff_freq= -1.0f,
|
||||||
{
|
.range=-1.0f
|
||||||
.can = BSP_CAN_1,
|
},
|
||||||
.id = 0x202,
|
.Radder_DIR_Angle={
|
||||||
.module = MOTOR_M3508,
|
.k=0.15f,
|
||||||
.reverse = false,
|
.p=0.20f,
|
||||||
.gear = true
|
.i=0.1f,
|
||||||
},
|
.d=0.001f,
|
||||||
{
|
.i_limit=1.0f,
|
||||||
.can = BSP_CAN_1,
|
.out_limit=30.0f,
|
||||||
.id = 0x203,
|
.d_cutoff_freq= -1.0f,
|
||||||
.module = MOTOR_M3508,
|
.range=360
|
||||||
.reverse = false,
|
},
|
||||||
.gear = true
|
.Wheel_DIR_Omega={
|
||||||
},
|
.k=0.5f,
|
||||||
{
|
.p=2.0f,
|
||||||
.can = BSP_CAN_1,
|
.i=0.1f,
|
||||||
.id = 0x204,
|
.d=0.7f,
|
||||||
.module = MOTOR_M3508,
|
.i_limit=1.0f,
|
||||||
.reverse = false,
|
.out_limit=1.0f,
|
||||||
.gear = true
|
.d_cutoff_freq= -1.0f,
|
||||||
},
|
.range=-1.0f
|
||||||
|
},
|
||||||
},
|
},
|
||||||
.type = CHASSIS_TYPE_MECANUM,
|
.motor={
|
||||||
/* PID */
|
.Wheel_DIR[0]={BSP_CAN_2,0x203,MOTOR_M3508,false,false},
|
||||||
.pid = {
|
.Wheel_DIR[1]={BSP_CAN_2,0x204,MOTOR_M3508,true,false},
|
||||||
/* µ×Å̵ç»ú PID */
|
.Wheel_DIR[2]={BSP_CAN_2,0x202,MOTOR_M3508,true,false},
|
||||||
.motor_pid_param = {
|
.Wheel_DIR[3]={BSP_CAN_2,0x201,MOTOR_M3508,false,false},
|
||||||
.k = 0.0015f,
|
|
||||||
.p = 1.0f,
|
|
||||||
.i = 0.0f,
|
|
||||||
.d = 0.0f,
|
|
||||||
.i_limit = 1.0f,
|
|
||||||
.out_limit = 1.0f,
|
|
||||||
.d_cutoff_freq = -1.0f,
|
|
||||||
.range = -1.0f,
|
|
||||||
},
|
|
||||||
|
|
||||||
/* ¸úËæ */
|
.Radder_DIR[0]={BSP_CAN_2,0x205,MOTOR_GM6020,false,false},
|
||||||
.follow_pid_param = {
|
.Radder_DIR[1]={BSP_CAN_2,0x206,MOTOR_GM6020,false,false},
|
||||||
.k = 1.2f,
|
.Radder_DIR[2]={BSP_CAN_2,0x207,MOTOR_GM6020,false,false},
|
||||||
.p = 1.0f,
|
.Radder_DIR[3]={BSP_CAN_2,0x208,MOTOR_GM6020,false,false},
|
||||||
.i = 0.5f,
|
|
||||||
.d = 0.01f,
|
|
||||||
.i_limit = 1.0f,
|
|
||||||
.out_limit = 1.0f,
|
|
||||||
.d_cutoff_freq = -1.0f,
|
|
||||||
.range = M_2PI,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
},
|
||||||
.low_pass_cutoff_freq = {
|
|
||||||
.in = 50.0f,
|
|
||||||
.out = 50.0f,
|
|
||||||
},
|
|
||||||
|
|
||||||
.reverse = {
|
|
||||||
.yaw = true,
|
|
||||||
},
|
|
||||||
.limit = {
|
|
||||||
.max_vx = 3.0f,
|
|
||||||
.max_vy = 3.0f,
|
|
||||||
.max_wz = 2.0f,
|
|
||||||
.max_current = 16000.0f
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.cmd_param={
|
.cmd_param={
|
||||||
.source_priority = {
|
.source_priority = {
|
||||||
CMD_SRC_RC,
|
CMD_SRC_RC,
|
||||||
@ -107,8 +77,8 @@ Config_RobotParam_t robot_config = {
|
|||||||
},
|
},
|
||||||
.rc_mode_map = {
|
.rc_mode_map = {
|
||||||
.sw_left_up = CHASSIS_MODE_RELAX,
|
.sw_left_up = CHASSIS_MODE_RELAX,
|
||||||
.sw_left_mid = CHASSIS_MODE_RELAX,
|
.sw_left_mid = RC,
|
||||||
.sw_left_down = CHASSIS_MODE_INDEPENDENT,
|
// .sw_left_down = ,
|
||||||
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ extern "C" {
|
|||||||
#include "component/PowerControl.h"
|
#include "component/PowerControl.h"
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// Arm_Params_t arm_param;
|
// Arm_Params_t arm_param;
|
||||||
Chassis_Params_t chassis_param;
|
Chassis_Param_t chassis_param;
|
||||||
CMD_Config_t cmd_param;
|
CMD_Config_t cmd_param;
|
||||||
} Config_RobotParam_t;
|
} Config_RobotParam_t;
|
||||||
|
|
||||||
|
|||||||
14
User/module/struct_typedef.h
Normal file
14
User/module/struct_typedef.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef STRUCT_TYPEDEF_H
|
||||||
|
#define STRUCT_TYPEDEF_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef unsigned char bool_t;
|
||||||
|
typedef float fp32;
|
||||||
|
typedef double fp64;
|
||||||
|
|
||||||
|
////
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -18,7 +18,7 @@
|
|||||||
/* USER STRUCT BEGIN */
|
/* USER STRUCT BEGIN */
|
||||||
Chassis_t chassis;
|
Chassis_t chassis;
|
||||||
Chassis_CMD_t chassis_cmd;
|
Chassis_CMD_t chassis_cmd;
|
||||||
Chassis_IMU_t chassis_imu;
|
//Chassis_IMU_t chassis_imu;
|
||||||
float max =50.0f;
|
float max =50.0f;
|
||||||
|
|
||||||
/* USER STRUCT END */
|
/* USER STRUCT END */
|
||||||
@ -37,25 +37,20 @@ void Task_ctrl_chassis(void *argument) {
|
|||||||
uint32_t tick = osKernelGetTickCount(); /* 控制任务运行频率的计时 */
|
uint32_t tick = osKernelGetTickCount(); /* 控制任务运行频率的计时 */
|
||||||
/* USER CODE INIT BEGIN */
|
/* USER CODE INIT BEGIN */
|
||||||
|
|
||||||
Config_RobotParam_t *cfg = Config_GetRobotParam();
|
chassis_init(&chassis, &Config_GetRobotParam()->chassis_param, CTRL_CHASSIS_FREQ);
|
||||||
Chassis_Init(&chassis, &cfg->chassis_param, (float)CTRL_CHASSIS_FREQ);
|
|
||||||
chassis.mech_zero=0.57f;
|
|
||||||
/* USER CODE INIT END */
|
/* USER CODE INIT END */
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
tick += delay_tick; /* 计算下一个唤醒时刻 */
|
tick += delay_tick; /* 计算下一个唤醒时刻 */
|
||||||
/* USER CODE BEGIN */
|
/* USER CODE BEGIN */
|
||||||
float encoder_gimbalYawMotor;
|
|
||||||
osMessageQueueGet(task_runtime.msgq.chassis.yaw, &encoder_gimbalYawMotor, NULL, 0);
|
|
||||||
osMessageQueueGet(task_runtime.msgq.chassis.cmd, &chassis_cmd, NULL, 0);
|
osMessageQueueGet(task_runtime.msgq.chassis.cmd, &chassis_cmd, NULL, 0);
|
||||||
chassis.feedback.encoder_gimbalYawMotor=encoder_gimbalYawMotor;
|
Chassis_update(&chassis);
|
||||||
|
Chassis_Control(&chassis, &chassis_cmd,tick);
|
||||||
|
Chassis_Setoutput(&chassis);
|
||||||
|
|
||||||
Chassis_UpdateFeedback(&chassis);
|
|
||||||
Chassis_Control(&chassis, &chassis_cmd, osKernelGetTickCount());
|
|
||||||
|
|
||||||
Chassis_Power_Control(&chassis,max);
|
|
||||||
|
|
||||||
Chassis_Output(&chassis);
|
|
||||||
/* USER CODE END */
|
/* USER CODE END */
|
||||||
osDelayUntil(tick); /* 运行结束,等待下一次唤醒 */
|
osDelayUntil(tick); /* 运行结束,等待下一次唤醒 */
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,7 +33,7 @@ void Task_Init(void *argument) {
|
|||||||
|
|
||||||
/* 创建任务线程 */
|
/* 创建任务线程 */
|
||||||
task_runtime.thread.blink = osThreadNew(Task_blink, NULL, &attr_blink);
|
task_runtime.thread.blink = osThreadNew(Task_blink, NULL, &attr_blink);
|
||||||
task_runtime.thread.arm_main = osThreadNew(Task_arm_main, NULL, &attr_arm_main);
|
//task_runtime.thread.arm_main = osThreadNew(Task_arm_main, NULL, &attr_arm_main);
|
||||||
task_runtime.thread.rc = osThreadNew(Task_rc, NULL, &attr_rc);
|
task_runtime.thread.rc = osThreadNew(Task_rc, NULL, &attr_rc);
|
||||||
task_runtime.thread.cmd = osThreadNew(Task_cmd, NULL, &attr_cmd);
|
task_runtime.thread.cmd = osThreadNew(Task_cmd, NULL, &attr_cmd);
|
||||||
task_runtime.thread.ctrl_chassis = osThreadNew(Task_ctrl_chassis, NULL, &attr_ctrl_chassis);
|
task_runtime.thread.ctrl_chassis = osThreadNew(Task_ctrl_chassis, NULL, &attr_ctrl_chassis);
|
||||||
|
|||||||
@ -32,7 +32,7 @@ OpenWindow="Memory 1", DockArea=BOTTOM, x=0, y=0, w=463, h=544, FilterBarShown=0
|
|||||||
OpenWindow="Watched Data 1", DockArea=RIGHT, x=0, y=0, w=903, h=930, TabPos=1, TopOfStack=1, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0
|
OpenWindow="Watched Data 1", DockArea=RIGHT, x=0, y=0, w=903, h=930, TabPos=1, TopOfStack=1, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0
|
||||||
OpenWindow="Functions", DockArea=LEFT, x=0, y=0, w=322, h=930, TabPos=1, TopOfStack=0, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0
|
OpenWindow="Functions", DockArea=LEFT, x=0, y=0, w=322, h=930, TabPos=1, TopOfStack=0, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0
|
||||||
OpenWindow="Data Sampling", DockArea=BOTTOM, x=2, y=0, w=725, h=525, TabPos=1, TopOfStack=1, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0, VisibleTab=0, UniformSampleSpacing=0
|
OpenWindow="Data Sampling", DockArea=BOTTOM, x=2, y=0, w=725, h=525, TabPos=1, TopOfStack=1, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0, VisibleTab=0, UniformSampleSpacing=0
|
||||||
OpenWindow="Timeline", DockArea=BOTTOM, x=1, y=0, w=1370, h=544, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=1, DataPaneShown=1, PowerPaneShown=0, CodePaneShown=0, PinCursor="Cursor Movable", TimePerDiv="200 ms / Div", TimeStampFormat="Time", DataGraphDrawAsPoints=0, DataGraphLegendShown=1, DataGraphUniformSampleSpacing=0, DataGraphLegendPosition="0;268", DataGraphShowNamesAtCursor=0, PowerGraphDrawAsPoints=0, PowerGraphLegendShown=0, PowerGraphAvgFilterTime=Off, PowerGraphAvgFilterLen=Off, PowerGraphUniformSampleSpacing=0, PowerGraphLegendPosition="1122;-71", CodeGraphLegendShown=0, CodeGraphLegendPosition="1138;0"
|
OpenWindow="Timeline", DockArea=BOTTOM, x=1, y=0, w=1370, h=544, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=1, DataPaneShown=1, PowerPaneShown=0, CodePaneShown=0, PinCursor="Cursor Movable", TimePerDiv="200 ms / Div", TimeStampFormat="Time", DataGraphDrawAsPoints=0, DataGraphLegendShown=1, DataGraphUniformSampleSpacing=0, DataGraphLegendPosition="0;268", DataGraphShowNamesAtCursor=0, PowerGraphDrawAsPoints=0, PowerGraphLegendShown=0, PowerGraphAvgFilterTime=Off, PowerGraphAvgFilterLen=Off, PowerGraphUniformSampleSpacing=0, PowerGraphLegendPosition="1122;-69", CodeGraphLegendShown=0, CodeGraphLegendPosition="1138;0"
|
||||||
OpenWindow="Console", DockArea=BOTTOM, x=2, y=0, w=725, h=525, TabPos=0, TopOfStack=0, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0
|
OpenWindow="Console", DockArea=BOTTOM, x=2, y=0, w=725, h=525, TabPos=0, TopOfStack=0, FilterBarShown=0, TotalValueBarShown=0, ToolBarShown=0
|
||||||
SmartViewPlugin="", Page="", Toolbar="Hidden", Window="SmartView 1"
|
SmartViewPlugin="", Page="", Toolbar="Hidden", Window="SmartView 1"
|
||||||
TableHeader="Registers 1", SortCol="Name", SortOrder="ASCENDING", VisibleCols=["Name";"Value";"Description"], ColWidths=[120;144;639]
|
TableHeader="Registers 1", SortCol="Name", SortOrder="ASCENDING", VisibleCols=["Name";"Value";"Description"], ColWidths=[120;144;639]
|
||||||
@ -42,7 +42,7 @@ TableHeader="RegisterSelectionDialog", SortCol="None", SortOrder="ASCENDING", Vi
|
|||||||
TableHeader="Source Files", SortCol="File", SortOrder="ASCENDING", VisibleCols=["File";"Status";"Size";"#Insts";"Path"], ColWidths=[215;100;100;100;1334]
|
TableHeader="Source Files", SortCol="File", SortOrder="ASCENDING", VisibleCols=["File";"Status";"Size";"#Insts";"Path"], ColWidths=[215;100;100;100;1334]
|
||||||
TableHeader="Watched Data 1", SortCol="Expression", SortOrder="ASCENDING", VisibleCols=["Expression";"Value";"Location";"Refresh";"Access"], ColWidths=[250;229;145;279;100]
|
TableHeader="Watched Data 1", SortCol="Expression", SortOrder="ASCENDING", VisibleCols=["Expression";"Value";"Location";"Refresh";"Access"], ColWidths=[250;229;145;279;100]
|
||||||
TableHeader="Data Sampling Table", SortCol="None", SortOrder="ASCENDING", VisibleCols=["Index";"Time";" ik_test_ret";" ik_test_ret_analytical";" ik_test_ret_numerical";" ik_test_solver_dbg"], ColWidths=[100;100;100;100;100;100]
|
TableHeader="Data Sampling Table", SortCol="None", SortOrder="ASCENDING", VisibleCols=["Index";"Time";" ik_test_ret";" ik_test_ret_analytical";" ik_test_ret_numerical";" ik_test_solver_dbg"], ColWidths=[100;100;100;100;100;100]
|
||||||
TableHeader="Data Sampling Setup", SortCol="Expression", SortOrder="ASCENDING", VisibleCols=["Expression";"Type";"Value";"Min";"Max";"Average";"# Changes";"Min. Change";"Max. Change"], ColWidths=[118;100;100;100;100;134;110;126;126]
|
TableHeader="Data Sampling Setup", SortCol="Expression", SortOrder="ASCENDING", VisibleCols=["Expression";"Type";"Value";"Min";"Max";"Average";"# Changes";"Min. Change";"Max. Change"], ColWidths=[118;100;124;124;124;104;110;126;126]
|
||||||
TableHeader="TargetExceptionDialog", SortCol="Name", SortOrder="ASCENDING", VisibleCols=["Name";"Value";"Address";"Description"], ColWidths=[200;100;100;340]
|
TableHeader="TargetExceptionDialog", SortCol="Name", SortOrder="ASCENDING", VisibleCols=["Name";"Value";"Address";"Description"], ColWidths=[200;100;100;340]
|
||||||
WatchedExpression="robot_arm", RefreshRate=5, Window=Watched Data 1
|
WatchedExpression="robot_arm", RefreshRate=5, Window=Watched Data 1
|
||||||
WatchedExpression="ik_from_fk_result", RefreshRate=5, Window=Watched Data 1
|
WatchedExpression="ik_from_fk_result", RefreshRate=5, Window=Watched Data 1
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user