#include "Arduino.h" #include "motocontrol.h" #include "moto.h" #include #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); }