You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

512 lines
18 KiB

/******************************************************************************
版权所有 (C), 2018-2099, Radkil
******************************************************************************
文 件 名 : motor_manager.c
版 本 号 : 初稿
作 者 : radkil
生成日期 : 2026年7月13日
最近修改 :
功能描述 : 电机管理模块(多实例管理,协议无关)
修改历史 :
1.日 期 : 2026年7月13日
作 者 : radkil
修改内容 : 创建文件
******************************************************************************/
#include "motor_manager.h"
/*----------------------------------------------*
* 外部变量说明 *
*----------------------------------------------*/
/*----------------------------------------------*
* 外部函数原型说明 *
*----------------------------------------------*/
/*----------------------------------------------*
* 内部函数原型说明 *
*----------------------------------------------*/
/*----------------------------------------------*
* 全局变量 *
*----------------------------------------------*/
/*----------------------------------------------*
* 模块级变量 *
*----------------------------------------------*/
static rd_slist_t g_stMotorList; // 电机链表头
/*----------------------------------------------*
* 常量定义 *
*----------------------------------------------*/
/*----------------------------------------------*
* 宏定义 *
*----------------------------------------------*/
// 宏:检查协议函数是否存在并调用
#define MOTOR_PROTOCOL_CALL(pstMotor, func, ...) \
((pstMotor)->m_pstProtocol && (pstMotor)->m_pstProtocol->func) ? \
(pstMotor)->m_pstProtocol->func(pstMotor, ##__VA_ARGS__) : RD_NULL
/*****************************************************************************
函 数 名 : MotorMgr_Init
功能描述 : 初始化电机管理模块
输入参数 : 无
输出参数 : 无
返 回 值 : void
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2026年7月13日
作 者 : radkil
修改内容 : 新生成函数
*****************************************************************************/
void MotorMgr_Init(void)
{
rd_slist_init(&g_stMotorList);
}
/*****************************************************************************
函 数 名 : MotorMgr_Create
功能描述 : 创建电机实例
输入参数 : const Motor_Config_t *pstConfig 电机配置
TComCtrl *ptCAN 绑定的CAN控制器
const Motor_Protocol_t *pstProtocol 协议操作函数表
void *pstPrivData 协议私有数据
输出参数 : 无
返 回 值 : Motor_Instance_t* 电机实例指针
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2026年7月13日
作 者 : radkil
修改内容 : 新生成函数
*****************************************************************************/
Motor_Instance_t* MotorMgr_Create(const Motor_Config_t *pstConfig,
TComCtrl *ptCAN,
const Motor_Protocol_t *pstProtocol,
void *pstPrivData)
{
if (NULL == pstConfig || NULL == ptCAN || NULL == pstProtocol)
{
return NULL;
}
// 检查是否已存在相同ID的电机
rd_slist_t *pos;
rd_slist_t *n;
rd_slist_for_each(pos, n, &g_stMotorList)
{
Motor_Instance_t *pstCheck = rd_slist_entry(pos, Motor_Instance_t, node);
if (pstCheck->m_stConfig.m_ucMotorID == pstConfig->m_ucMotorID)
{
return NULL; // ID重复
}
}
// 分配内存
Motor_Instance_t *pstMotor = (Motor_Instance_t *)RD_CALLOC(1, sizeof(Motor_Instance_t));
if (NULL == pstMotor)
{
return NULL;
}
// 初始化链表节点
pstMotor->node.next = NULL;
// 复制配置
pstMotor->m_stConfig.m_ucMotorID = pstConfig->m_ucMotorID;
pstMotor->m_stConfig.m_uiPulsePerRound = pstConfig->m_uiPulsePerRound > 0 ? pstConfig->m_uiPulsePerRound : 10000;
pstMotor->m_stConfig.m_uiReductionRatio = pstConfig->m_uiReductionRatio > 0 ? pstConfig->m_uiReductionRatio : 70;
pstMotor->m_stConfig.m_fWheelDiameter = pstConfig->m_fWheelDiameter > 0 ? pstConfig->m_fWheelDiameter : 0.26f;
// 初始化运行数据
pstMotor->m_stData.m_iRealPosition = 0;
pstMotor->m_stData.m_iRealVelocity = 0;
pstMotor->m_stData.m_iRealTorque = 0;
pstMotor->m_stData.m_uiFaultCode = 0;
pstMotor->m_stData.m_dRealDistance = 0.0;
pstMotor->m_stData.m_iStartMeasurePos = 0;
pstMotor->m_stData.m_iLastPosition = 0;
pstMotor->m_stData.m_iRoundCount = 0;
pstMotor->m_stData.m_ucStartMeasureFlag = 1;
// 绑定CAN控制器和协议
pstMotor->m_ptCAN = ptCAN;
pstMotor->m_eState = MOTOR_STATE_IDLE;
pstMotor->m_uiLastHeartbeat = 0;
pstMotor->m_pstProtocol = pstProtocol;
pstMotor->m_pstPrivData = pstPrivData;
// 设置实例名称
RD_SNPRINTF(pstMotor->m_szName, MOTOR_MAX_NAME_LEN, "Motor_%d", pstConfig->m_ucMotorID);
// 添加到链表尾部
rd_slist_append(&g_stMotorList, &pstMotor->node);
return pstMotor;
}
/*****************************************************************************
函 数 名 : MotorMgr_Destroy
功能描述 : 销毁电机实例
输入参数 : Motor_Instance_t *pstMotor 电机实例
输出参数 : 无
返 回 值 : int 0成功,非0失败
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2026年7月13日
作 者 : radkil
修改内容 : 新生成函数
*****************************************************************************/
int MotorMgr_Destroy(Motor_Instance_t *pstMotor)
{
if (NULL == pstMotor)
{
return RD_NULL;
}
// 从链表中移除
rd_slist_remove(&g_stMotorList, &pstMotor->node);
RD_FREE(pstMotor);
return RD_SUCCESS;
}
/*****************************************************************************
函 数 名 : MotorMgr_FindByName
功能描述 : 通过名称查找电机实例
输入参数 : const char *pszName 实例名称
输出参数 : 无
返 回 值 : Motor_Instance_t* 电机实例指针
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2026年7月13日
作 者 : radkil
修改内容 : 新生成函数
*****************************************************************************/
Motor_Instance_t* MotorMgr_FindByName(const char *pszName)
{
if (NULL == pszName)
{
return NULL;
}
rd_slist_t *pos;
rd_slist_t *n;
rd_slist_for_each(pos, n, &g_stMotorList)
{
Motor_Instance_t *pstMotor = rd_slist_entry(pos, Motor_Instance_t, node);
if (RD_STRCMP(pstMotor->m_szName, pszName) == 0)
{
return pstMotor;
}
}
return NULL;
}
/*****************************************************************************
函 数 名 : MotorMgr_FindByID
功能描述 : 通过ID查找电机实例
输入参数 : uint8_t ucMotorID 电机节点ID
输出参数 : 无
返 回 值 : Motor_Instance_t* 电机实例指针
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2026年7月13日
作 者 : radkil
修改内容 : 新生成函数
*****************************************************************************/
Motor_Instance_t* MotorMgr_FindByID(uint8_t ucMotorID)
{
rd_slist_t *pos;
rd_slist_t *n;
rd_slist_for_each(pos, n, &g_stMotorList)
{
Motor_Instance_t *pstMotor = rd_slist_entry(pos, Motor_Instance_t, node);
if (pstMotor->m_stConfig.m_ucMotorID == ucMotorID)
{
return pstMotor;
}
}
return NULL;
}
/*****************************************************************************
函 数 名 : MotorMgr_ResetAll
功能描述 : 复位所有节点
输入参数 : Motor_Instance_t *pstMotor 电机实例
输出参数 : 无
返 回 值 : int 0成功,非0失败
*****************************************************************************/
int MotorMgr_ResetAll(Motor_Instance_t *pstMotor)
{
return MOTOR_PROTOCOL_CALL(pstMotor, pfResetAll);
}
/*****************************************************************************
函 数 名 : MotorMgr_ActivateAll
功能描述 : 激活所有节点
输入参数 : Motor_Instance_t *pstMotor 电机实例
输出参数 : 无
返 回 值 : int 0成功,非0失败
*****************************************************************************/
int MotorMgr_ActivateAll(Motor_Instance_t *pstMotor)
{
return MOTOR_PROTOCOL_CALL(pstMotor, pfActivateAll);
}
/*****************************************************************************
函 数 名 : MotorMgr_SetHome
功能描述 : 设置当前位置为零点
输入参数 : Motor_Instance_t *pstMotor 电机实例
输出参数 : 无
返 回 值 : int 0成功,非0失败
*****************************************************************************/
int MotorMgr_SetHome(Motor_Instance_t *pstMotor)
{
return MOTOR_PROTOCOL_CALL(pstMotor, pfSetHome);
}
/*****************************************************************************
函 数 名 : MotorMgr_SetWatchdog
功能描述 : 设置看门狗时间
输入参数 : Motor_Instance_t *pstMotor 电机实例
uint32_t uiTimeMs 毫秒
输出参数 : 无
返 回 值 : int 0成功,非0失败
*****************************************************************************/
int MotorMgr_SetWatchdog(Motor_Instance_t *pstMotor, uint32_t uiTimeMs)
{
return MOTOR_PROTOCOL_CALL(pstMotor, pfSetWatchdog, uiTimeMs);
}
/*****************************************************************************
函 数 名 : MotorMgr_RequestPosition
功能描述 : 读取电机位置
输入参数 : Motor_Instance_t *pstMotor 电机实例
输出参数 : 无
返 回 值 : int 0成功,非0失败
*****************************************************************************/
int MotorMgr_RequestPosition(Motor_Instance_t *pstMotor)
{
return MOTOR_PROTOCOL_CALL(pstMotor, pfRequestPosition);
}
/*****************************************************************************
函 数 名 : MotorMgr_RequestVelocity
功能描述 : 读取电机速度
输入参数 : Motor_Instance_t *pstMotor 电机实例
输出参数 : 无
返 回 值 : int 0成功,非0失败
*****************************************************************************/
int MotorMgr_RequestVelocity(Motor_Instance_t *pstMotor)
{
return MOTOR_PROTOCOL_CALL(pstMotor, pfRequestVelocity);
}
/*****************************************************************************
函 数 名 : MotorMgr_RequestTorque
功能描述 : 读取电机电流/转矩
输入参数 : Motor_Instance_t *pstMotor 电机实例
输出参数 : 无
返 回 值 : int 0成功,非0失败
*****************************************************************************/
int MotorMgr_RequestTorque(Motor_Instance_t *pstMotor)
{
return MOTOR_PROTOCOL_CALL(pstMotor, pfRequestTorque);
}
/*****************************************************************************
函 数 名 : MotorMgr_RequestFault
功能描述 : 读取故障码
输入参数 : Motor_Instance_t *pstMotor 电机实例
输出参数 : 无
返 回 值 : int 0成功,非0失败
*****************************************************************************/
int MotorMgr_RequestFault(Motor_Instance_t *pstMotor)
{
return MOTOR_PROTOCOL_CALL(pstMotor, pfRequestFault);
}
/*****************************************************************************
函 数 名 : MotorMgr_SpeedModeInit
功能描述 : 速度模式初始化
输入参数 : Motor_Instance_t *pstMotor 电机实例
输出参数 : 无
返 回 值 : int 0成功,非0失败
*****************************************************************************/
int MotorMgr_SpeedModeInit(Motor_Instance_t *pstMotor)
{
int iRet = MOTOR_PROTOCOL_CALL(pstMotor, pfSpeedModeInit);
if (iRet == RD_SUCCESS)
{
pstMotor->m_eState = MOTOR_STATE_READY;
}
return iRet;
}
/*****************************************************************************
函 数 名 : MotorMgr_SetTargetSpeed
功能描述 : 设置目标速度
输入参数 : Motor_Instance_t *pstMotor 电机实例
int32_t iTargetSpeed 目标速度(脉冲/秒)
输出参数 : 无
返 回 值 : int 0成功,非0失败
*****************************************************************************/
int MotorMgr_SetTargetSpeed(Motor_Instance_t *pstMotor, int32_t iTargetSpeed)
{
int iRet = MOTOR_PROTOCOL_CALL(pstMotor, pfSetTargetSpeed, iTargetSpeed);
if (iRet == RD_SUCCESS)
{
pstMotor->m_eState = MOTOR_STATE_RUNNING;
}
return iRet;
}
/*****************************************************************************
函 数 名 : MotorMgr_PositionModeInit
功能描述 : 位置模式初始化
输入参数 : Motor_Instance_t *pstMotor 电机实例
int32_t iAccel 加速度(脉冲/秒²)
int32_t iDecel 减速度(脉冲/秒²)
int32_t iTargetSpeed 目标速度(脉冲/秒)
输出参数 : 无
返 回 值 : int 0成功,非0失败
*****************************************************************************/
int MotorMgr_PositionModeInit(Motor_Instance_t *pstMotor, int32_t iAccel, int32_t iDecel, int32_t iTargetSpeed)
{
int iRet = MOTOR_PROTOCOL_CALL(pstMotor, pfPositionModeInit, iAccel, iDecel, iTargetSpeed);
if (iRet == RD_SUCCESS)
{
pstMotor->m_eState = MOTOR_STATE_READY;
}
return iRet;
}
/*****************************************************************************
函 数 名 : MotorMgr_SetTargetPosition
功能描述 : 设置目标位置(相对运动)
输入参数 : Motor_Instance_t *pstMotor 电机实例
int32_t iTargetPos 目标位置(脉冲)
输出参数 : 无
返 回 值 : int 0成功,非0失败
*****************************************************************************/
int MotorMgr_SetTargetPosition(Motor_Instance_t *pstMotor, int32_t iTargetPos)
{
int iRet = MOTOR_PROTOCOL_CALL(pstMotor, pfSetTargetPosition, iTargetPos);
if (iRet == RD_SUCCESS)
{
pstMotor->m_eState = MOTOR_STATE_RUNNING;
}
return iRet;
}
/*****************************************************************************
函 数 名 : MotorMgr_SetDO
功能描述 : 设置数字输出
输入参数 : Motor_Instance_t *pstMotor 电机实例
uint8_t ucDoIndex 输出索引(1或2)
uint8_t ucState 状态(0或1)
输出参数 : 无
返 回 值 : int 0成功,非0失败
*****************************************************************************/
int MotorMgr_SetDO(Motor_Instance_t *pstMotor, uint8_t ucDoIndex, uint8_t ucState)
{
return MOTOR_PROTOCOL_CALL(pstMotor, pfSetDO, ucDoIndex, ucState);
}
/*****************************************************************************
函 数 名 : MotorMgr_ParseResponse
功能描述 : 解析CAN响应数据(遍历所有电机实例尝试解析)
输入参数 : uint8_t ucMotorID 电机节点ID
const uint8_t *pucData 数据指针
uint32_t uiLen 数据长度
输出参数 : 无
返 回 值 : void
*****************************************************************************/
void MotorMgr_ParseResponse(uint8_t ucMotorID, const uint8_t *pucData, uint32_t uiLen)
{
if (NULL == pucData || uiLen < 8)
{
return;
}
Motor_Instance_t *pstMotor = MotorMgr_FindByID(ucMotorID);
if (NULL == pstMotor)
{
return;
}
if (pstMotor->m_pstProtocol && pstMotor->m_pstProtocol->pfParseResponse)
{
pstMotor->m_pstProtocol->pfParseResponse(pstMotor, pucData, uiLen);
}
}
/*****************************************************************************
函 数 名 : MotorMgr_SpeedConvert
功能描述 : 速度单位转换
输入参数 : Motor_Instance_t *pstMotor 电机实例
int32_t iSpeedUserUnit 用户速度单位
输出参数 : 无
返 回 值 : int32_t 脉冲/秒
*****************************************************************************/
int32_t MotorMgr_SpeedConvert(Motor_Instance_t *pstMotor, int32_t iSpeedUserUnit)
{
if (pstMotor->m_pstProtocol && pstMotor->m_pstProtocol->pfSpeedConvert)
{
return pstMotor->m_pstProtocol->pfSpeedConvert(pstMotor, iSpeedUserUnit);
}
return 0;
}
/*****************************************************************************
函 数 名 : MotorMgr_GetData
功能描述 : 获取电机数据
输入参数 : Motor_Instance_t *pstMotor 电机实例
输出参数 : 无
返 回 值 : const Motor_Data_t*
*****************************************************************************/
const Motor_Data_t* MotorMgr_GetData(Motor_Instance_t *pstMotor)
{
if (NULL == pstMotor)
{
return NULL;
}
return &pstMotor->m_stData;
}
/*****************************************************************************
函 数 名 : MotorMgr_GetState
功能描述 : 获取电机状态
输入参数 : Motor_Instance_t *pstMotor 电机实例
输出参数 : 无
返 回 值 : Motor_State_e
*****************************************************************************/
Motor_State_e MotorMgr_GetState(Motor_Instance_t *pstMotor)
{
if (NULL == pstMotor)
{
return MOTOR_STATE_IDLE;
}
return pstMotor->m_eState;
}