Files
edc-mcu/components/actuator/actuator.h
T
2026-07-31 17:51:37 +08:00

240 lines
7.1 KiB
C
Raw 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.
/**
* @file actuator.h
* @brief 执行器应用层封装 — 4 路步进电机 + 1 路舵机
*
* 轴映射:
* 1 号电机 (addr=1) ── Angle/Z 旋转轴
* 2 号电机 (addr=2) ── X 轴
* 3 号电机 (addr=3) ── Y 轴 ─┐ 完全同步
* 4 号电机 (addr=4) ── Y 轴 ─┘
* 舵机 (PWM) ── Z 轴抬升 (仅抬起/放下两态)
*
* 运动模式: 位置模式, 绝对定位 (raF=true), 暂不标定
*/
#ifndef ACTUATOR_H
#define ACTUATOR_H
#include <stdint.h>
#include <stdbool.h>
#include "driver/gpio.h"
#include "protocol.h"
#include "emm_v5.h"
#ifdef __cplusplus
extern "C" {
#endif
/* ================================================================
* 可配置宏 (可在项目级或 -D 覆盖)
* ================================================================ */
/** 丝杆参数 (X / Y 轴直线运动) */
#define ACTUATOR_SCREW_LEAD_MM 8.0f /* 导程: 一圈 = 8mm 直线位移 */
#define ACTUATOR_SCREW_PITCH_MM 2.0f /* 螺距 */
/** 电机 Emm_V5 地址 */
#ifndef ACTUATOR_ADDR_ANGLE
#define ACTUATOR_ADDR_ANGLE 1 /* Angle / Z 旋转轴 */
#endif
#ifndef ACTUATOR_ADDR_X
#define ACTUATOR_ADDR_X 2 /* X 轴 */
#endif
#ifndef ACTUATOR_ADDR_Y1
#define ACTUATOR_ADDR_Y1 3 /* Y 轴 #1 (同步) */
#endif
#ifndef ACTUATOR_ADDR_Y2
#define ACTUATOR_ADDR_Y2 4 /* Y 轴 #2 (同步) */
#endif
/** 舵机 PWM GPIO */
#ifndef ACTUATOR_SERVO_GPIO
#define ACTUATOR_SERVO_GPIO GPIO_NUM_4
#endif
/** 电机 UART 引脚 */
#ifndef ACTUATOR_UART_PORT
#define ACTUATOR_UART_PORT UART_NUM_1
#endif
#ifndef ACTUATOR_UART_TX
#define ACTUATOR_UART_TX GPIO_NUM_6
#endif
#ifndef ACTUATOR_UART_RX
#define ACTUATOR_UART_RX GPIO_NUM_7
#endif
/** 默认速度 (RPM, 0~5000) */
#ifndef ACTUATOR_DEFAULT_VEL
#define ACTUATOR_DEFAULT_VEL 500
#endif
/** 默认加速度 (0~255, 0=直接启动) */
#ifndef ACTUATOR_DEFAULT_ACC
#define ACTUATOR_DEFAULT_ACC 50
#endif
/** 脉冲换算系数 (坐标值 × scale = 脉冲数)
*
* X/Y 轴: 丝杆导程 8mm → 一圈 8mm = 3200 脉冲
* scale = 3200 / 8 = 400 脉冲/mm
*
* Z 旋转: angle_x10 单位为 0.1°
* 一圈 360° = 3600 (0.1°) = 3200 脉冲
* scale = 3200 / 3600 ≈ 0.8889 脉冲/(0.1°)
*/
#ifndef ACTUATOR_SCALE_X
#define ACTUATOR_SCALE_X 400.0f /* mm → 脉冲 */
#endif
#ifndef ACTUATOR_SCALE_Y
#define ACTUATOR_SCALE_Y 400.0f /* mm → 脉冲 */
#endif
#ifndef ACTUATOR_SCALE_ANGLE
#define ACTUATOR_SCALE_ANGLE ((float)EMM_V5_PULSES_PER_REV / 3600.0f) /* 0.1° → 脉冲 */
#endif
/** 便捷宏: mm 直线距离 → 脉冲数 (四舍五入) */
#define ACTUATOR_MM_TO_PULSES(mm) ((uint32_t)((float)(mm) * ACTUATOR_SCALE_X + 0.5f))
/** 软限位 (左上零点坐标系, 单位 mm) */
#define ACTUATOR_LIMIT_X_MIN 0.0f
#define ACTUATOR_LIMIT_X_MAX 210.0f
#define ACTUATOR_LIMIT_Y_MIN 0.0f
#define ACTUATOR_LIMIT_Y_MAX 335.0f
/** Fragment 间等待 (ms), 暂用固定延时替代到位检测 */
#ifndef ACTUATOR_FRAG_DELAY_MS
#define ACTUATOR_FRAG_DELAY_MS 500
#endif
/**
* 连续多帧之间的间隔 (ms)
* Emm_V5 驱动板无法解析 UART 上零间隔的背靠背连续帧 (会丢字节),
* 凡是一次动作需要连发多帧 (如 Y 轴双电机), 帧间必须插入该延时
*/
#ifndef ACTUATOR_FRAME_GAP_MS
#define ACTUATOR_FRAME_GAP_MS 10
#endif
/** 控制模式: 2 = 闭环位置模式 */
#define ACTUATOR_CTRL_MODE 2
/**
* XY 平面左上零点坐标系 运动方向:
* X 轴正向 (→): CW (dir=0) ── 电机2
* Y 轴正向 (↓): CCW (dir=1) ── 电机3+4 (双电机同步)
* Z 旋转正向 (↻): CW (dir=0) ── 电机1
*/
#define ACTUATOR_DIR_X 0 /* X轴正向 = CW */
#define ACTUATOR_DIR_Y 1 /* Y轴正向 = CCW */
#define ACTUATOR_DIR_ANGLE 0 /* Z旋转正向 = CW */
/* ================================================================
* API
* ================================================================ */
/**
* @brief 初始化所有执行器
* @note 内部调用 Emm_V5_Init + servo_init + 4 路电机使能 + 闭环模式
*/
void actuator_init(void);
/**
* @brief 设置脉冲换算系数
* @param x_scale X 轴: 坐标值 × x_scale = 脉冲数
* @param y_scale Y 轴: 坐标值 × y_scale = 脉冲数
* @param angle_scale Z 旋转: angle_x10 × angle_scale = 脉冲数
*/
void actuator_set_scale(float x_scale, float y_scale, float angle_scale);
/**
* @brief 执行一个完整 Cycle (遍历所有 Fragment, 逐段运动)
* @param cycle 协议下发的 Cycle 数据
* @return 0 成功, -1 参数无效
*/
int actuator_execute_cycle(const edc_cycle_t *cycle);
/**
* @brief 急停全部 4 路电机
*/
void actuator_stop_all(void);
/**
* @brief 舵机: 抬起 (上限位)
*/
void actuator_servo_up(void);
/**
* @brief 舵机: 放下 (下限位)
*/
void actuator_servo_down(void);
/**
* @brief 舵机: 设置任意角度
* @param angle 角度 0.0 ~ 180.0
*/
void actuator_servo_set_angle(float angle);
/* ---- 单电机手动控制 (Web 调试用, Y 轴自动同步) ---- */
/**
* @brief 单电机使能控制 (Y 轴电机各自独立)
* @param addr 电机地址 (1~4)
* @param state 使能状态
*/
void actuator_motor_enable(uint8_t addr, bool state);
/**
* @brief 单电机速度模式 (Y 轴地址 3/4 自动同步)
* @param addr 电机地址 (1~4)
* @param dir 方向, 0=CW, 非0=CCW
* @param vel 速度 0~5000 RPM
* @param acc 加速度 0~255
*/
void actuator_motor_vel(uint8_t addr, uint8_t dir, uint16_t vel, uint8_t acc);
/**
* @brief 单电机位置模式 (Y 轴地址 3/4 自动同步)
* @param addr 电机地址 (1~4)
* @param dir 方向, 0=CW, 非0=CCW
* @param vel 速度 0~5000 RPM
* @param acc 加速度 0~255
* @param clk 脉冲数
* @param raF 相对/绝对, false=相对, true=绝对
*/
void actuator_motor_pos(uint8_t addr, uint8_t dir, uint16_t vel, uint8_t acc,
uint32_t clk, bool raF);
/**
* @brief 单电机角度直控 (Y 轴地址 3/4 自动同步)
* @param addr 电机地址 (1~4)
* @param angle_deg 目标角度 (°), 内部换算为脉冲 (3200=360°)
* @param vel 速度 0~5000 RPM
* @param acc 加速度 0~255
* @param raF 相对/绝对, false=相对, true=绝对
*/
void actuator_motor_angle(uint8_t addr, float angle_deg, uint16_t vel,
uint8_t acc, bool raF);
/**
* @brief 单电机直线距离控制 (X/Y 轴, Y 轴地址 3/4 自动同步)
* @param addr 电机地址 (2=X, 3/4=Y)
* @param distance_mm 直线移动距离 (mm), 丝杆导程 8mm/圈
* @param vel 速度 0~5000 RPM
* @param acc 加速度 0~255
* @param raF 相对/绝对, false=相对, true=绝对
*/
void actuator_motor_mm(uint8_t addr, float distance_mm, uint16_t vel,
uint8_t acc, bool raF);
/**
* @brief 单电机立即停止 (Y 轴地址 3/4 自动同步)
* @param addr 电机地址 (1~4)
*/
void actuator_motor_stop(uint8_t addr);
#ifdef __cplusplus
}
#endif
#endif /* ACTUATOR_H */