4

高校のプロジェクトでエレベーターのようなロボットを設計およびプログラミングしています。これをもっと簡単にするために何かできることはありますか?それとも良いですか?AutoCAD Inventor で作成したラベル付きのデザインの写真を添付し​​ました。

ここに画像の説明を入力

RobotC または VEX (C および C++ と非常によく似ています) に慣れていない方向け: リミット スイッチ (limit1、limit2、...) とバンプ スイッチ (floor1、floor2、...) はアナログ ボタンであり、値を返します。押されていない場合は 0、押されている場合は 1 です。モーター (mainMotor) がギアを回転させ、メカニズムがスライド上を上向きに移動します。モーター機構から突き出たシャフトが上下に動くと、リミットスイッチを押して値1を返します。

int callup [3];
int calldown [3];
int floorat[3];

    int main ()
    {

        if (SensorValue[limit1] == 1)
        {
            floorat[0] = 1;
        }
        else
        {
            floorat[0] = 0;
        }

        if (SensorValue[limit2] == 1)
        {
            floorat[1] = 1;
        }
        else
        {
            floorat[1] = 0;
        }

        if (SensorValue[limit3] == 1)
        {
            floorat[2] = 1;
        }
        else
        {
            floorat[2] = 0;
        }

        if (SensorValue[floor1] == 1)
        {
            calldown[0] = 1;
            SensorValue[LED1] = 1;
        }

        if (SensorValue[floor2] == 1 && floorat[2] == 1)
        {
            calldown[1] = 1;
            SensorValue[LED2] = 1;
        }

        if (SensorValue[floor2] == 1 && floorat[0] == 1)
        {
            callup[1] = 1;
            SensorValue[LED2] = 1;
        }

        if (SensorValue[floor3])
        {
            callup[2] = 1;
            SensorValue[LED3] = 1;
        }

        motors ();

    }


    void motors ()
    {

        if (callup[2] == 1 && floorat[2] == 1)
        {
            int x = 1;
            while (x < 3)
            {
                SensorValue[LED3] = 1;
                wait(0.5);
                SensorValue[LED3] = 0;
                wait(0.5);
            }
            callup[2] = 0;
            main ();
        }
        else if (callup[1] == 1 && floorat[1] == 1)
        {
            int x = 1;
            while (x < 3)
            {
                SensorValue[LED2] = 1;
                wait(0.5);
                SensorValue[LED2] = 0;
                wait(0.5);
            }
            callup[1] = 0;
            main ();
        }
        else if (callup[0] == 1 && floorat[0] == 1)
        {
            int x = 1;
            while (x < 3)
            {
                SensorValue[LED1] = 1;
                wait(0.5);
                SensorValue[LED1] = 0;
                wait(0.5);
            }
            callup[0] = 0;
            main ();
        }

        if (callup[2] == 1 && floorat[1] == 1 && calldown[0] == 0 || callup[2] == 1 && floorat[0] == 1 && callup[1] == 0)
        {
            startMotor(mainMotor, 60);
            untilTouch(limit3);
            stopMotor(mainMotor);
            callup[2] = 0;
            wait(1);
            main ();
        }

        if (callup[1] == 1 && floorat[0] == 1)
        {
            startMotor(mainMotor, 60);
            untilTouch(limit2);
            stopMotor(mainMotor);
            callup[1] = 0;
            wait(1);
            main();
        }

        if (calldown[1] == 1 && floorat[2] == 1)
        {
            startMotor(mainMotor, -60);
            untilTouch(limit2);
            stopMotor(mainMotor);
            calldown[1] = 0;
            wait(1);
            main();
        }

        if (calldown[0] == 1 && floorat[2] == 1 && calldown[1] == 0 || calldown[0] == 1 && floorat[1] == 1)
        {
            startMotor(mainMotor, -60);
            untilTouch(limit1);
            stopMotor(mainMotor);
            calldown[0] = 0;
            wait(1);
            main();
        }
    }

この質問には関係ありませんが、わかりやすくするために、startMotor コマンドの 60 はモーターの速度です。

ご不明な点がございましたら、お気軽にお問い合わせください。

4

3 に答える 3

3

特定の瞬間におけるエレベータの状態を定義しましょう。

エレベータは、上昇下降、またはアイドル状態になることができます。

ここに画像の説明を入力

エレベーターは特定のにあり、スイッチをトリガーすると、ある階から別の階に移動します。

ここに画像の説明を入力

さて、これを擬似コードに変換すると(簡単に変換できるはずですRobotC):

enum elevator_status = { idle, down, up };
int currentfloor; //1, 2, 3 


switch(elevator_status)
{
    case idle:    
        //we check if a button is pressed and possibly go up or down           
        if(SensorValue(floor1))
        {         
             if(currentfloor > 1)
                elevator_status = down;               
        }
        else if(SensorValue(floor2))
        {
              if(currentfloor > 2)
                  elevator_status = down;
              else if(currentfloor < 2)
                  elevator_status = up;               
        }
        else if(SensorValue(floor3))
        {
              if(currentfloor < 3)
                  elevator_status = up;   
        }
        break;

    case up:
    case down:    
        //we check if we trigger a floor switch and stop the elevator
        if(SensorValue(limit1))
        {      
           currentfloor = 1;
           elevator_status = idle;
        }
        else if(SensorValue(limit2))
        {
           currentfloor = 2;
           elevator_status = idle;
        }
        else if(SensorValue(limit3))
        {
           currentfloor = 3;
           elevator_status = idle;
        }
        break;
}


//we set the speed of the motor
if(elevator_status == up)
{
   set_motorstate(cw);
)
else if(elevator_status == down)
{
   set_motorstate(ccw);   
}
else if(elevator_status == idle)
{
   set_motorstate(idle);   
}

注 : このコードでは、エレベータは、エレベータがアイドル状態の場合にのみ、新しい上下フロア呼び出しを処理します。移動中にアップダウン コールを保存せず、後でそこに移動します。それがあなたの要件だったかどうかはわかりません。

于 2013-11-09T22:07:30.950 に答える
2

私は RobotC や VEX に詳しくありませんが、独自の関数にすることができる一定量の複製された操作に気付きました。

次のコード スニペットは、個別の関数にします。したがって、 motors と呼ばれる大きな関数には、次の一連の操作があります。

    int x = 1;
    while (x < 3)
    {
        SensorValue[LED3] = 1;
        wait(0.5);
        SensorValue[LED3] = 0;
        wait(0.5);
    }
    callup[2] = 0;
    main ();

これは、わずかに異なる値で繰り返されます。

ここでは、次のような関数を記述します。

void adjust_sensors( size_t led, size_t level )
{
    int x = 1;
    while (x < 3)
    {
        SensorValue[led] = 1;
        wait(0.5);
        SensorValue[led] = 0;
        wait(0.5);
    }
    callup[level] = 0;
    main ();
}

次のコードでも同じことができます。

startMotor(mainMotor, 60);
untilTouch(limit3);
stopMotor(mainMotor);
callup[2] = 0;
wait(1);
main ();

また、x の値が変化しないため、while ループが終了しないようです。

次のように宣言すると、上部にもタイプミスがあります。

int callown [2];

私はあなたが意味したと思います:

int calldown [2];

わかりやすくするために、コードにコメントを追加することもお勧めします。

お役に立てれば。

于 2013-11-09T21:51:54.327 に答える
2

私は自分自身の質問をしている学生にすぎませんが、配列のサイズを間違えたようです。たとえば、次のように宣言した場合:

int floorat[2];

これにより、配列のサイズは 2 になりました。次に、この配列の 3 つの要素の位置 [0、1、2] を参照します。また、通常の整数を使用して、値 1、2、または 3 を割り当てることはできませんか?

これらの変数を次のように再定義することをお勧めします。

int callup;
int calldown;
int floorat;

次に、余分なコード行を避け、if/else 句を次のように簡素化できます。

if (SensorValue[limit1] == 1)
{
    floorat = 1;
}

if (SensorValue[limit2] == 1)
{
    floorat = 2;
}


if (SensorValue[limit3] == 1)
{
    floorat = 3;
}
于 2013-11-09T21:45:36.043 に答える