【RobotC編程】程序限位

【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); }}

在Graphical RobotC for VEX中,只能通過兩個if條件結構的「嵌套」實現此功能

程序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);}

推薦閱讀:

TAG:VEX機器人 | C編程語言 | 機器人教育 |