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.

513 lines
18 KiB

/******************************************************************************
(C), 2018-2099, Radkil
******************************************************************************
: motor_manager.c
: 稿
: radkil
: 2026713
:
:
:
1. : 2026713
: 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. : 2026713
: 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. : 2026713
: 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 00
:
:
:
1. : 2026713
: 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. : 2026713
: 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. : 2026713
: 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 00
*****************************************************************************/
int MotorMgr_ResetAll(Motor_Instance_t *pstMotor)
{
return MOTOR_PROTOCOL_CALL(pstMotor, pfResetAll);
}
/*****************************************************************************
: MotorMgr_ActivateAll
:
: Motor_Instance_t *pstMotor
:
: int 00
*****************************************************************************/
int MotorMgr_ActivateAll(Motor_Instance_t *pstMotor)
{
return MOTOR_PROTOCOL_CALL(pstMotor, pfActivateAll);
}
/*****************************************************************************
: MotorMgr_SetHome
:
: Motor_Instance_t *pstMotor
:
: int 00
*****************************************************************************/
int MotorMgr_SetHome(Motor_Instance_t *pstMotor)
{
return MOTOR_PROTOCOL_CALL(pstMotor, pfSetHome);
}
/*****************************************************************************
: MotorMgr_SetWatchdog
:
: Motor_Instance_t *pstMotor
uint32_t uiTimeMs
:
: int 00
*****************************************************************************/
int MotorMgr_SetWatchdog(Motor_Instance_t *pstMotor, uint32_t uiTimeMs)
{
return MOTOR_PROTOCOL_CALL(pstMotor, pfSetWatchdog, uiTimeMs);
}
/*****************************************************************************
: MotorMgr_RequestPosition
:
: Motor_Instance_t *pstMotor
:
: int 00
*****************************************************************************/
int MotorMgr_RequestPosition(Motor_Instance_t *pstMotor)
{
return MOTOR_PROTOCOL_CALL(pstMotor, pfRequestPosition);
}
/*****************************************************************************
: MotorMgr_RequestVelocity
:
: Motor_Instance_t *pstMotor
:
: int 00
*****************************************************************************/
int MotorMgr_RequestVelocity(Motor_Instance_t *pstMotor)
{
return MOTOR_PROTOCOL_CALL(pstMotor, pfRequestVelocity);
}
/*****************************************************************************
: MotorMgr_RequestTorque
: /
: Motor_Instance_t *pstMotor
:
: int 00
*****************************************************************************/
int MotorMgr_RequestTorque(Motor_Instance_t *pstMotor)
{
return MOTOR_PROTOCOL_CALL(pstMotor, pfRequestTorque);
}
/*****************************************************************************
: MotorMgr_RequestFault
:
: Motor_Instance_t *pstMotor
:
: int 00
*****************************************************************************/
int MotorMgr_RequestFault(Motor_Instance_t *pstMotor)
{
return MOTOR_PROTOCOL_CALL(pstMotor, pfRequestFault);
}
/*****************************************************************************
: MotorMgr_SpeedModeInit
:
: Motor_Instance_t *pstMotor
:
: int 00
*****************************************************************************/
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 00
*****************************************************************************/
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 00
*****************************************************************************/
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 00
*****************************************************************************/
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 (12)
uint8_t ucState (01)
:
: int 00
*****************************************************************************/
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;
}