【RobotC編程】程序限位
來自專欄玩轉VEX IQ機器人
與「物理限位」相對,當我們熟悉馬達編碼器(Encoder)和RobotC編程語言後,會更多地採用「程序限位」,而非「物理限位」,使機器人更加自動化和智能。
程序1:顯示抬升馬達的Encoder(編碼器)值
#pragma config(Motor, motor3, lift, tmotorVexIQ, PIDControl, encoder)//*!!Code automaticaaally generated by ROBOTC configuration wizard!!*//task main(){ resetMotorEncoder(lift); while(1){ displayCenteredBigTextLine(2,"%d",getMotorEncoder(lift)); }}
這是一個「測試測量」Encoder值的程序,無需使用TeleOP模式,可以直接採用Autonomous模式下載和調試程序。下載完畢後,機器人即可在NEXT LEVEL場地中「手動」抬升馬達,實時測量、LCD屏幕顯示第二層Hub(得分物)的高度對應的Encoder值。
解釋說明:
①抬升馬達(lift)的初始化複位:
resetMotorEncoder(lift);
②啟動程序前,需將機器人的抬升馬達壓到「最低」,以此作為Encoder的值為零的「基準線」。
程序2:遙控手柄上BtnRUp、BtnRDown兩個按鈕控制抬升馬達(lift)的升降
#pragma config(Motor, motor3, lift, tmotorVexIQ, PIDControl, encoder)//*!!Code aautomaticaaally generated by ROBOTC configuration wizard!!*//task main(){ resetMotorEncoder(lift); while(1){//Lift if(getJoystickValue(BtnRUp)==1){ setMotorSpeed(lift,100); } if(getJoystickValue(BtnRDown)==1){ setMotorSpeed(lift,-100); } if(getJoystickValue(BtnRUp)==0 && getJoystickValue(BtnRDown)==0){ setMotorSpeed(lift,0); } }}
解釋說明:
此處通過「與」運算(&&),要求getJoystickValue(BtnRUp)==0和getJoystickValue(BtnRDown)==0這兩個條件「同時」滿足。
「與」運算「等效替代」了兩個if分支嵌套的方法:
if(getJoystickValue(BtnRUp)==0){ if(getJoystickValue(BtnRDown)==0){ setMotorSpeed(lift,0); }}
程序3:加入一鍵(One-Key)控制抬升馬達升降到限定位置的模塊//One-key
(「程序限位」模塊)
#pragma config(Motor, motor3, lift, tmotorVexIQ, PIDControl, encoder)//*!!Code aautomaticaaally generated by ROBOTC configuration wizard!!*//task main(){ resetMotorEncoder(lift); while(1){//Lift if(getJoystickValue(BtnRUp)==1){ setMotorSpeed(lift,100); } if(getJoystickValue(BtnRDown)==1){ setMotorSpeed(lift,-100); } if(getJoystickValue(BtnRUp)==0 && getJoystickValue(BtnRDown)==0){ setMotorSpeed(lift,0); }//One-key if(getJoystickValue(BtnFUp)==1){ if(getMotorEncoder(lift)<600){ setMotorSpeed(lift,100); while(getMotorEncoder(lift)<600){;} setMotorSpeed(lift,0); } else{ setMotorSpeed(lift,-100); while(getMotorEncoder(lift)>600){;} setMotorSpeed(lift,0); } } displayCenteredBigTextLine(2,"%d",getMotorEncoder(lift)); }}
解釋說明:
①其中的if條件結構:
if(getMotorEncoder(lift)<600){ …}else{ …}
用於判斷當前馬達的位置是在「限位值」600的上方還是下方,並相應採取下降或上升,兩個不同的方向來靠近Encoder限位值,直到停止。
②控制馬達的「漢堡包」法則:
setMotorSpeed(lift,100);while(getMotorEncoder(lift)<600){;}setMotorSpeed(lift,0);
和
setMotorSpeed(lift,-100);while(getMotorEncoder(lift)>600){;}setMotorSpeed(lift,0);
此處的while條件循環類似於「wait until…」,確定條件,而不確定使用時間。
程序4:嵌入底盤遙控程序模塊//arcade control
#pragma config(Motor, motor1, left, tmotorVexIQ, PIDControl, encoder)#pragma config(Motor, motor2, right, tmotorVexIQ, PIDControl, encoder)#pragma config(Motor, motor3, lift, tmotorVexIQ, PIDControl, encoder)//*!!Code aautomaticaaally generated by ROBOTC configuration wizard!!*//task main(){ resetMotorEncoder(lift); while(1){//arcade control int spdL=getJoystickValue(ChC) + getJoystickValue(ChA); int spdR=getJoystickValue(ChC) - getJoystickValue(ChA); setMotorSpeed(left ,-spdL); setMotorSpeed(right,-spdR);//Lift if(getJoystickValue(BtnRUp)==1){ setMotorSpeed(lift,100); } if(getJoystickValue(BtnRDown)==1){ setMotorSpeed(lift,-100); } if(getJoystickValue(BtnRUp)==0 && getJoystickValue(BtnRDown)==0){ setMotorSpeed(lift,0); }//One-key if(getJoystickValue(BtnFUp)==1){ if(getMotorEncoder(lift)<600){ setMotorSpeed(lift,100); while(getMotorEncoder(lift)<600){;} setMotorSpeed(lift,0); } else{ setMotorSpeed(lift,-100); while(getMotorEncoder(lift)>600){;} setMotorSpeed(lift,0); } } displayCenteredBigTextLine(2,"%d",getMotorEncoder(lift)); }}
課後思考問題:
(1)如何在//arcade control模塊中,做到遙控器(joystick)搖桿(ChA/ChC)的閾值修正?
(2)如何在//One-key模塊運行時,臨時關閉以下(//Lift模塊)這段代碼的「許可權」,以避免「競爭機制」的產生?
//當BtnRUp和BtnRDown未按下時,關閉抬升馬達if(getJoystickValue(BtnRUp)==0 && getJoystickValue(BtnRDown)==0){ setMotorSpeed(lift,0);}
推薦閱讀: