PullupDev/src/motocontrol.cpp

340 lines
8.4 KiB
C++
Raw Normal View History

#include "Arduino.h"
#include "motocontrol.h"
#include "moto.h"
#include <ESP32Servo.h>
#include "config.h"
#define DEBUG_OUT false
Motocontrol::Motocontrol()
{
_controlstatus.is_instore = false;
_controlstatus.is_setzero = false;
_controlstatus.is_overweight = false;
_controlstatus.zero_cnt = 0;
_controlstatus.motostatus = MotoStatus::MS_Stop;
_controlstatus.speed_targe = SPEED_BTN_SLOW;
_check_targetlength = false;
_need_closemoto = false;
_pullweight = 0;
_curr_length = 0.0;
_hooksstatus = HS_UnInit;
_weightalign = false;
_overweightcount = 0;
_autogoodsdown=false;
}
Motocontrol::~Motocontrol()
{
}
bool Motocontrol::init(Servo *lockservo) // 初始化
{
_lockservo = lockservo;
return _moto_dji.init();
}
void Motocontrol::setspeed(float motospeed) // 设置速度
{
_controlstatus.speed_targe = motospeed;
}
void Motocontrol::setweight(int pullweight) // 设置重量
{
_pullweight = pullweight;
checkoverweight();
}
void Motocontrol::checkoverweight() // 检测是否超重
{
// 到顶部锁定状态,有向上的压力,重量不准,不能检测
if (_controlstatus.is_toplocked)
return;
if (_pullweight > HOOK_WEIHT_MAX)
{
// 防止毛刺
_overweightcount++;
if (_overweightcount > 5)
_controlstatus.is_overweight = true;
}
else
{
_controlstatus.is_overweight = false;
_overweightcount = 0;
}
}
void Motocontrol::stop() // 停止
{
_moto_dji.settarget(0.0f);
_controlstatus.motostatus = MS_Stop;
_hooksstatus = HS_Stop;
_lockservo->write(SERVO_LOCKPOS);
_need_closemoto = true;
_tm_closemoto = millis();
printf("write servo :%d \n", SERVO_LOCKPOS);
printf("stop \n");
}
void Motocontrol::setlocked(bool locked)
{
if (locked)
{
stop();
setzero();
}
_controlstatus.is_toplocked = locked;
_hooksstatus = HS_Locked;
}
void Motocontrol::setzero() // 设置0长度位置
{
// 记录0长度位置--以后需要保存到falsh里面
_controlstatus.zero_cnt = getmotoinfo().output_round_cnt;
_controlstatus.is_setzero = true;
}
int16_t Motocontrol::getlength() // 得到长度
{
return 0;
}
// 检测是否挂有货物
bool Motocontrol::havegoods()
{
return _pullweight > HOOK_WEIHT_MIN;
}
// 检测是否挂有货物
void Motocontrol::goodsstartup()
{
moto_run(MS_Stop);
setspeed(SPEED_HOOK_UP);
moto_run(MS_Up);
_hooksstatus = HS_Up;
}
// 重量传感器已经校准
void Motocontrol::weightalign(bool weightalign)
{
_weightalign = weightalign;
}
void Motocontrol::checkhookstatus() // 检查挂钩状态
{
//需要在自动放货物中
if (!_autogoodsdown) return;
_hook_currlen = _curr_length;
switch (_hooksstatus)
{
// 正在下放货物
case HookStatus::HS_Down:
{
// 如果没有货物--开始回收
if (!havegoods())
{
goodsstartup();
break;
}
// 如果有长度目标
if (_hook_targetlen > 0)
{
// 如果停了就开始慢速
if (_controlstatus.motostatus == MS_Stop)
{
// 慢速一直下放,直到货物卸下--没有重量
setspeed(SPEED_HOOK_SLOW);
moto_run(MS_Down);
_hooksstatus = HS_DownSlow;
}
}
else
{
// 没有长度目标,如果停了并且货物还在,一般是线到最大了,所有开始回收
if (_controlstatus.motostatus == MS_Stop)
goodsstartup();
}
break;
}
case HookStatus::HS_DownSlow:
{
if (!havegoods())
{
goodsstartup();
}
break;
}
case HookStatus::HS_Up:
{
if (_controlstatus.is_instore)
_hooksstatus = HS_InStore;
break;
}
case HookStatus::HS_InStore:
{
if (_controlstatus.is_toplocked)
{
_autogoodsdown=false;
_hooksstatus = HS_Locked;
}
break;
}
}
}
void Motocontrol::checkmotostatus() // 检查电机状态,比如什么时候停
{
// 1秒后断电防止电调堵转保护
if ((_need_closemoto) && ((millis() - _tm_closemoto) > 1000))
_moto_dji.close();
moto_measure_t mf = _moto_dji.getmotoinfo();
// 已设置零点
if (_controlstatus.is_setzero)
{
// 总放线长度
_curr_length = abs(mf.output_round_cnt - _controlstatus.zero_cnt) * WHEEL_PERIMETER;
// 不能超ROPE_MAXLENGTH
if ((_curr_length > ROPE_MAXLENGTH) && (_controlstatus.motostatus == MS_Down))
stop();
// 开始入仓
if ((_curr_length < INSTORE_LENGTH) && (_controlstatus.motostatus == MotoStatus::MS_Up))
{
_moto_dji.settarget(-SPEED_INSTORE);
_controlstatus.is_instore = true;
}
else
_controlstatus.is_instore = false;
}
if (_check_targetlength) // 有目标长度
{
if (_controlstatus.motostatus == MS_Down)
{
if (mf.output_round_cnt > _target_cnt)
{
printf("cnt:%.2f ,tar:%.2f\n", mf.output_round_cnt, _target_cnt);
stop();
}
}
else if (_controlstatus.motostatus == MS_Up)
{
if (mf.output_round_cnt < _target_cnt)
{
printf("cnt:%.2f ,tar:%.2f\n", mf.output_round_cnt, _target_cnt);
stop();
}
}
}
}
void Motocontrol::update() // 更新
{
_moto_dji.update();
checkmotostatus();
checkhookstatus();
}
void Motocontrol::direct_speed(float motospeed) // 直接控制电机--测试用
{
_moto_dji.settarget(motospeed);
}
moto_measure_t Motocontrol::getmotoinfo()
{
return _moto_dji.getmotoinfo();
}
control_status_t Motocontrol::getcontrolstatus() // 得到控制信息
{
return _controlstatus;
}
void Motocontrol::moto_goodsdown(float length)
{
// 没设置零点
if (!_controlstatus.is_setzero)
{
printf("not lengthzero fault\n");
return;
}
if (_weightalign)
{
printf("weight not align fault\n");
return;
}
// 没挂东西也没设置下放长度
if (!havegoods() && (length == 0.0))
{
printf("goods min fault:%d ,len:%.2f\n", _pullweight, length);
return;
}
//开始自动放货物状态
_autogoodsdown=true;
_hook_targetlen = length;
if (length == 0.0)
setspeed(SPEED_HOOK_CHECK);
else
setspeed(SPEED_HOOK_FAST);
if (length > 0)
moto_run(MS_Down, length - HOOK_SLOWDOWN_LENGTH);
else
moto_run(MS_Down);
_hooksstatus = HS_Down;
}
// 按指定速度收放线 放线为+,收线为- 单位cm
void Motocontrol::moto_run(MotoStatus updown, float length)
{
// 传入要stop直接停
if (updown == MS_Stop)
{
stop();
return;
}
// 运动中暂时不管
if ((_controlstatus.motostatus == MS_Down) || (_controlstatus.motostatus == MS_Up))
{
printf("motostatus is MS_Down\\MS_Up \n");
return;
}
// 没设置速度不转
if (_controlstatus.speed_targe == 0)
{
printf("not set speed_targe \n");
return;
}
if (updown == MS_Up)
{
if (_controlstatus.is_overweight)
{
printf("overweight fault :%d \n", _pullweight);
return;
}
}
_lockservo->write(SERVO_UNLOCKPOS);
_need_closemoto = false;
printf("write servo :%d \n", SERVO_UNLOCKPOS);
_controlstatus.motostatus = updown;
// 有长度限制
if (length != 0)
{
// 收需要负
if (updown == MotoStatus::MS_Up)
length = -length;
// 记录开始位置
_start_cnt = _moto_dji.getmotoinfo().output_round_cnt;
_target_cnt = _start_cnt + length / WHEEL_PERIMETER;
_check_targetlength = true;
}
else
_check_targetlength = false;
// 记录开始位置
float runspeed;
if (updown == MotoStatus::MS_Down)
runspeed = _controlstatus.speed_targe;
else
{
// 如果没有设置零点,不能快速收线
if (!_controlstatus.is_setzero)
_controlstatus.speed_targe = SPEED_BTN_SLOW;
runspeed = -_controlstatus.speed_targe;
}
// 开始转
printf("run speed:%.0f,tarcnt:%.2f\n", runspeed, _target_cnt);
_moto_dji.settarget(runspeed);
}