|
|
@ -1,4 +1,6 @@ |
|
|
|
#include "xy_robot_ctrl_module.hpp"
|
|
|
|
|
|
|
|
#include "sdk/components/errorcode/errorcode.hpp"
|
|
|
|
using namespace iflytop; |
|
|
|
using namespace std; |
|
|
|
#define TAG "XYRobotCtrlModule"
|
|
|
@ -7,91 +9,295 @@ void XYRobotCtrlModule::initialize(IStepperMotor* stepM1, // |
|
|
|
ZGPIO* Xgpio, //
|
|
|
|
ZGPIO* Ygpio, //
|
|
|
|
float distanceK) { |
|
|
|
m_stepM1 = stepM1; |
|
|
|
m_stepM2 = stepM2; |
|
|
|
m_Xgpio = Xgpio; |
|
|
|
m_Ygpio = Ygpio; |
|
|
|
m_distanceK = distanceK; |
|
|
|
m_stepM1 = stepM1; |
|
|
|
m_stepM2 = stepM2; |
|
|
|
m_Xgpio = Xgpio; |
|
|
|
m_Ygpio = Ygpio; |
|
|
|
ZASSERT(m_stepM1); |
|
|
|
ZASSERT(m_stepM2); |
|
|
|
ZASSERT(m_Xgpio); |
|
|
|
ZASSERT(m_Ygpio); |
|
|
|
m_stepM1->setDistanceK(distanceK); |
|
|
|
m_stepM2->setDistanceK(distanceK); |
|
|
|
m_lock.init(); |
|
|
|
m_statu_lock.init(); |
|
|
|
m_thread.init("XYRobotCtrlModule", 1024, osPriorityNormal); |
|
|
|
} |
|
|
|
|
|
|
|
void XYRobotCtrlModule::dumpcfg(const char* tag) { |
|
|
|
ZLOGI(TAG, "======dumpcfg:%s=========", tag); |
|
|
|
ZLOGI(TAG, "= m_cfg_acc :%d", m_cfg_acc); |
|
|
|
ZLOGI(TAG, "= m_cfg_dec :%d", m_cfg_dec); |
|
|
|
ZLOGI(TAG, "= m_cfg_velocity :%d", m_cfg_velocity); |
|
|
|
ZLOGI(TAG, "= m_cfg_runtozero_maxX :%d", m_cfg_runtozero_maxX); |
|
|
|
ZLOGI(TAG, "= m_cfg_runtozero_maxY :%d", m_cfg_runtozero_maxY); |
|
|
|
ZLOGI(TAG, "= m_cfg_runtozero_speed :%d", m_cfg_runtozero_speed); |
|
|
|
ZLOGI(TAG, "= m_cfg_runtozero_dec :%d", m_cfg_runtozero_dec); |
|
|
|
ZLOGI(TAG, "="); |
|
|
|
} |
|
|
|
int32_t XYRobotCtrlModule::set_zero_robottype(RobotType_t robot_type) { |
|
|
|
m_robot_type = robot_type; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
int32_t XYRobotCtrlModule::set_x_shaft(bool x_shaft) { |
|
|
|
m_x_shaft = x_shaft; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
int32_t XYRobotCtrlModule::set_y_shaft(bool y_shaft) { |
|
|
|
m_y_shaft = y_shaft; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
int32_t XYRobotCtrlModule::enable(bool venable) { |
|
|
|
zlock_guard lock(m_lock); |
|
|
|
|
|
|
|
ZLOGI(TAG, "enable:%d", venable); |
|
|
|
m_stepM1->enable(venable); |
|
|
|
m_stepM2->enable(venable); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
int32_t XYRobotCtrlModule::getMotor1Pos() { return m_stepM1->getXACTUAL() * m_distanceK; } |
|
|
|
int32_t XYRobotCtrlModule::getMotor2Pos() { return m_stepM2->getXACTUAL() * m_distanceK; } |
|
|
|
|
|
|
|
void XYRobotCtrlModule::getNowPos(int32_t& x, int32_t& y) { |
|
|
|
// y=M1+M2;
|
|
|
|
// X=m1-m2;
|
|
|
|
x = getMotor1Pos() - getMotor2Pos(); |
|
|
|
y = getMotor1Pos() + getMotor2Pos(); |
|
|
|
} |
|
|
|
|
|
|
|
int32_t XYRobotCtrlModule::move_to(int32_t x, int32_t y) { |
|
|
|
zlock_guard lock(m_lock); |
|
|
|
ZLOGI(TAG, "move_to x:%d y:%d", x, y); |
|
|
|
int32_t m1pos, m2pos; |
|
|
|
inverse_kinematics(x, y, m1pos, m2pos); |
|
|
|
|
|
|
|
m_thread.stop(); |
|
|
|
m_thread.start([this,m1pos,m2pos]() { |
|
|
|
ZLOGI("XYRobotCtrlModule", "m1pos:%d m2pos:%d", m1pos, m2pos); |
|
|
|
/**
|
|
|
|
* @TODO:添加限位检查 |
|
|
|
*/ |
|
|
|
updateStatus(1); |
|
|
|
m_thread.start([this, x, y]() { |
|
|
|
_motor_move_to(x, y, m_cfg_velocity, m_cfg_acc, m_cfg_dec); |
|
|
|
while (!_motor_is_reach_target()) { |
|
|
|
if (m_thread.getExitFlag()) break; |
|
|
|
vTaskDelay(10); |
|
|
|
} |
|
|
|
_motor_stop(); |
|
|
|
updateStatus(0); |
|
|
|
}); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
int32_t XYRobotCtrlModule::move_by(int32_t dx, int32_t dy) { |
|
|
|
zlock_guard lock(m_lock); |
|
|
|
ZLOGI(TAG, "move_by dx:%d dy:%d", dx, dy); |
|
|
|
return 0; |
|
|
|
int32_t now_x, now_y; |
|
|
|
getnowpos(now_x, now_y); |
|
|
|
return move_to(now_x + dx, now_y + dy); |
|
|
|
} |
|
|
|
|
|
|
|
int32_t XYRobotCtrlModule::move_to_zero() { |
|
|
|
zlock_guard lock(m_lock); |
|
|
|
ZLOGI(TAG, "move_to_zero"); |
|
|
|
|
|
|
|
updateStatus(1); |
|
|
|
m_thread.stop(); |
|
|
|
m_thread.start([this]() { |
|
|
|
int32_t erro = exec_move_to_zero_task(); |
|
|
|
if (erro != 0) { |
|
|
|
ZLOGI(TAG, "exec_move_to_zero_task failed:%d", erro); |
|
|
|
updateStatus(0); |
|
|
|
return; |
|
|
|
} |
|
|
|
m_stepM1->setXACTUAL(0); |
|
|
|
m_stepM2->setXACTUAL(0); |
|
|
|
updateStatus(0); |
|
|
|
return; |
|
|
|
}); |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
int32_t XYRobotCtrlModule::move_to_with_calibrate(int32_t x, int32_t y) { |
|
|
|
zlock_guard lock(m_lock); |
|
|
|
ZLOGI(TAG, "move_to_with_calibrate x:%d y:%d", x, y); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
int32_t XYRobotCtrlModule::stop() { |
|
|
|
zlock_guard lock(m_lock); |
|
|
|
ZLOGI(TAG, "stop"); |
|
|
|
m_thread.stop(); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
uint8_t XYRobotCtrlModule::read_status(uint8_t* module_statu, int32_t* x, int32_t* y) { return 0; } |
|
|
|
|
|
|
|
int32_t XYRobotCtrlModule::set_acc(int32_t acc) { |
|
|
|
zlock_guard lock(m_lock); |
|
|
|
ZLOGI(TAG, "set_acc acc:%d", acc); |
|
|
|
m_cfg_acc = acc; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
int32_t XYRobotCtrlModule::set_dec(int32_t dec) { |
|
|
|
zlock_guard lock(m_lock); |
|
|
|
ZLOGI(TAG, "set_dec dec:%d", dec); |
|
|
|
m_cfg_dec = dec; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
int32_t XYRobotCtrlModule::set_speed(int32_t speed) { |
|
|
|
zlock_guard lock(m_lock); |
|
|
|
ZLOGI(TAG, "set_speed speed:%d", speed); |
|
|
|
m_cfg_velocity = speed; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
int32_t XYRobotCtrlModule::set_runtozero_maxX(int32_t maxX) { |
|
|
|
zlock_guard lock(m_lock); |
|
|
|
ZLOGI(TAG, "set_runtozero_maxX:%d", maxX); |
|
|
|
m_cfg_runtozero_maxX = maxX; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
int32_t XYRobotCtrlModule::set_runtozero_maxY(int32_t maxY) { |
|
|
|
zlock_guard lock(m_lock); |
|
|
|
ZLOGI(TAG, "set_runtozero_maxY:%d", maxY); |
|
|
|
m_cfg_runtozero_maxY = maxY; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
int32_t XYRobotCtrlModule::set_runtozero_speed(int32_t speed) { |
|
|
|
zlock_guard lock(m_lock); |
|
|
|
ZLOGI(TAG, "set_runtozero_speed:%d", speed); |
|
|
|
m_cfg_runtozero_speed = speed; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
int32_t XYRobotCtrlModule::set_runtozero_dec(int32_t dec) { |
|
|
|
zlock_guard lock(m_lock); |
|
|
|
ZLOGI(TAG, "set_runtozero_dec:%d", dec); |
|
|
|
m_cfg_runtozero_dec = dec; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
int32_t XYRobotCtrlModule::set_runtozero_leave_away_zero_maxXY(int32_t maxXY) { |
|
|
|
zlock_guard lock(m_lock); |
|
|
|
ZLOGI(TAG, "set_runtozero_leave_away_zero_maxXY:%d", maxXY); |
|
|
|
m_cfg_runtozero_leave_away_zero_maxXY = maxXY; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
int32_t XYRobotCtrlModule::set_distance_scale(float distance_scale) { |
|
|
|
zlock_guard lock(m_lock); |
|
|
|
ZLOGI(TAG, "set_distance_scale:%f", distance_scale); |
|
|
|
m_stepM1->setDistanceK(distance_scale); |
|
|
|
m_stepM2->setDistanceK(distance_scale); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
void XYRobotCtrlModule::loop() {} |
|
|
|
|
|
|
|
void XYRobotCtrlModule::forward_kinematics(int32_t m1pos, int32_t m2pos, int32_t& x, int32_t& y) { |
|
|
|
#if 1
|
|
|
|
x = m1pos - m2pos; |
|
|
|
y = m1pos + m2pos; |
|
|
|
#else
|
|
|
|
x = m1pos + m2pos; |
|
|
|
y = m1pos - m2pos; |
|
|
|
#endif
|
|
|
|
} |
|
|
|
void XYRobotCtrlModule::inverse_kinematics(int32_t x, int32_t y, int32_t& m1pos, int32_t& m2pos) { |
|
|
|
#if 1
|
|
|
|
m1pos = (x + y) / 2; |
|
|
|
m2pos = (y - x) / 2; |
|
|
|
#else
|
|
|
|
m1pos = (x - y) / 2; |
|
|
|
m2pos = (x + y) / 2; |
|
|
|
#endif
|
|
|
|
} |
|
|
|
int32_t XYRobotCtrlModule::exec_move_to_zero_task() { |
|
|
|
/*******************************************************************************
|
|
|
|
* 移动X轴到零点 * |
|
|
|
*******************************************************************************/ |
|
|
|
_motor_move_by(m_cfg_runtozero_maxX, 0, m_cfg_runtozero_speed, m_cfg_acc, m_cfg_runtozero_dec); |
|
|
|
bool xreach_zero = false; |
|
|
|
while (true) { |
|
|
|
// ZLOGI(TAG, "xgpio %d %d %d", m_Xgpio->getState(), m_stepM1->isReachTarget(), m_stepM2->isReachTarget());
|
|
|
|
if (m_Xgpio->getState()) { |
|
|
|
xreach_zero = true; |
|
|
|
_motor_stop(-1); |
|
|
|
break; |
|
|
|
} |
|
|
|
vTaskDelay(1); |
|
|
|
} |
|
|
|
|
|
|
|
if (!xreach_zero) { |
|
|
|
// 触发异常回调
|
|
|
|
ZLOGE(TAG, "x reach zero failed"); |
|
|
|
return err::kcommon_error_not_found_x_zero_point; |
|
|
|
} |
|
|
|
ZLOGI(TAG, "x reach zero"); |
|
|
|
/*******************************************************************************
|
|
|
|
* 移动Y轴到零点 * |
|
|
|
*******************************************************************************/ |
|
|
|
_motor_move_by(0, m_cfg_runtozero_maxY, m_cfg_runtozero_speed, m_cfg_acc, m_cfg_runtozero_dec); |
|
|
|
bool yreach_zero = false; |
|
|
|
while (!_motor_is_reach_target()) { |
|
|
|
// ZLOGI(TAG, "ygpio %d", m_Ygpio->getState());
|
|
|
|
if (m_Ygpio->getState()) { |
|
|
|
yreach_zero = true; |
|
|
|
_motor_stop(-1); |
|
|
|
break; |
|
|
|
} |
|
|
|
vTaskDelay(1); |
|
|
|
} |
|
|
|
if (!yreach_zero) { |
|
|
|
// 触发异常回调
|
|
|
|
ZLOGE(TAG, "y reach zero failed"); |
|
|
|
return err::kcommon_error_not_found_y_zero_point; |
|
|
|
} |
|
|
|
ZLOGI(TAG, "y reach zero"); |
|
|
|
ZLOGI(TAG, "move_to_zero success"); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
void XYRobotCtrlModule::updateStatus(uint8_t status) { |
|
|
|
zlock_guard lock(m_statu_lock); |
|
|
|
m_status = status; |
|
|
|
} |
|
|
|
void XYRobotCtrlModule::getnowpos(int32_t& x, int32_t& y) { |
|
|
|
int32_t m1pos, m2pos; |
|
|
|
m1pos = m_stepM1->getXACTUAL(); |
|
|
|
m2pos = m_stepM1->getXACTUAL(); |
|
|
|
inverse_kinematics(m1pos, m2pos, x, y); |
|
|
|
} |
|
|
|
void XYRobotCtrlModule::_motor_move_to(int32_t x, int32_t y, int32_t maxv, int32_t acc, int32_t dec) { |
|
|
|
ZLOGI(TAG, "_motor_move_to x:%d y:%d maxv:%d,acc:%d,dec:%d", x, y, maxv, acc, dec); |
|
|
|
int32_t target_m1pos, target_m2pos; |
|
|
|
forward_kinematics(x, y, target_m1pos, target_m2pos); |
|
|
|
m_stepM1->setAcceleration(acc); |
|
|
|
m_stepM2->setAcceleration(acc); |
|
|
|
|
|
|
|
m_stepM1->setDeceleration(dec); |
|
|
|
m_stepM2->setDeceleration(dec); |
|
|
|
|
|
|
|
m_stepM1->moveTo(target_m1pos, maxv); |
|
|
|
m_stepM2->moveTo(target_m2pos, maxv); |
|
|
|
} |
|
|
|
|
|
|
|
void XYRobotCtrlModule::_motor_move_by(int32_t dx, int32_t dy, int32_t maxv, int32_t acc, int32_t dec) { |
|
|
|
// ZLOGI(TAG, "_motor_move_by dx:%d dy:%d", dx, dy);
|
|
|
|
ZLOGI(TAG, "_motor_move_by dx:%d dy:%d maxv:%d acc:%d dec:%d ", dx, dy, maxv, acc, dec); |
|
|
|
int32_t t_x, t_y; |
|
|
|
getnowpos(t_x, t_y); |
|
|
|
t_x = t_x + dx; |
|
|
|
t_y = t_y + dy; |
|
|
|
|
|
|
|
int32_t target_m1pos, target_m2pos; |
|
|
|
forward_kinematics(t_x, t_y, target_m1pos, target_m2pos); |
|
|
|
|
|
|
|
m_stepM1->setAcceleration(acc); |
|
|
|
m_stepM2->setAcceleration(acc); |
|
|
|
|
|
|
|
m_stepM1->setDeceleration(dec); |
|
|
|
m_stepM2->setDeceleration(dec); |
|
|
|
ZLOGI(TAG, "_motor_move_by target_m1pos:%d target_m2pos:%d", target_m1pos, target_m2pos); |
|
|
|
m_stepM1->moveTo(target_m1pos, maxv); |
|
|
|
m_stepM2->moveTo(target_m2pos, maxv); |
|
|
|
} |
|
|
|
void XYRobotCtrlModule::_motor_stop(int32_t dec) { |
|
|
|
if (dec > 0) { |
|
|
|
m_stepM1->setDeceleration(dec); |
|
|
|
m_stepM2->setDeceleration(dec); |
|
|
|
} |
|
|
|
m_stepM1->stop(); |
|
|
|
m_stepM2->stop(); |
|
|
|
} |
|
|
|
void XYRobotCtrlModule::inverse_kinematics(int32_t m1pos, int32_t m2pos, int32_t& x, int32_t& y) { |
|
|
|
if (m_robot_type == corexy) { |
|
|
|
x = (m1pos - m2pos); |
|
|
|
y = (m1pos + m2pos); |
|
|
|
} else { |
|
|
|
x = m1pos + m2pos; |
|
|
|
y = m1pos - m2pos; |
|
|
|
} |
|
|
|
if (m_x_shaft) x = -x; |
|
|
|
if (m_y_shaft) y = -y; |
|
|
|
} |
|
|
|
void XYRobotCtrlModule::forward_kinematics(int32_t x, int32_t y, int32_t& m1pos, int32_t& m2pos) { |
|
|
|
if (m_x_shaft) x = -x; |
|
|
|
if (m_y_shaft) y = -y; |
|
|
|
|
|
|
|
if (m_robot_type == corexy) { |
|
|
|
m1pos = ((x + y) / 2); |
|
|
|
m2pos = ((y - x) / 2); |
|
|
|
} else { |
|
|
|
m1pos = (x - y) / 2; |
|
|
|
m2pos = (x + y) / 2; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
bool XYRobotCtrlModule::_motor_is_reach_target() { return m_stepM1->isReachTarget() && m_stepM2->isReachTarget(); } |