arrayswhile-looprotationrobotrobotc

RobotC Sonar Sensor Array


I am using a sonar sensor to create an obstacle avoiding robot. The robot needs to be able to check 180 degrees in front of it, so I have made a "head" the sensor is mounted on that is attached to a motor with an axle that runs through a potentiometer. I have found the potentiometer values for the 5 sets of 45 degree intervals with the total 180 degrees required and documented. The sonar sensor must be able to scan a distance and then move 45 degrees, repeating the process until it reaches 180 degrees (to the right) only once it reaches that point of rotation, the scan distances are put into an array to be used by an avoidance task to be developed at a later time. However, the sonar sensor stores values for certain angles before the head has actually reached that specified angle. Obstacle Avoidance Robot (Head rotation system in the middle)

  #pragma config(Sensor, in1,    headrot,        sensorPotentiometer)
#pragma config(Sensor, dgtl1,  fsonar,         sensorSONAR_inch)
#pragma config(Sensor, dgtl3,  bsonar,         sensorSONAR_inch)
#pragma config(Sensor, dgtl5,  steerrot,       sensorQuadEncoder)
#pragma config(Sensor, dgtl7,  wheelrot,       sensorQuadEncoder)
#pragma config(Motor,  port2,           head,          tmotorVex393_MC29, openLoop)
#pragma config(Motor,  port4,           drivem,        tmotorVex393_MC29, openLoop)
#pragma config(Motor,  port5,           steer,         tmotorVex393_MC29, openLoop)

int headrotationspeed = 25;
int frontscandistance[5]; //Array that hold each of the 5 angles at 45 degree intervals
int headangle =0;
task avoidance()
{
}
task frontscanner()
{
    //0 Degrees = 3500
    //45 Degrees = 2800
    //90 Degrees = 1900
    //135 Degrees = 1200
    //180 Degrees = 530
    while(true)
    {
        switch(headangle)
        {
        case 0:
            while(SensorValue[headrot]<3500 && SensorValue[headrot]>3400)
            {
                motor[head]=-headrotationspeed;
            }
                motor[head]=0;
            frontscandistance[0] = SensorValue[fsonar];
            headangle+=45;
            break;

        case 45:
            while(SensorValue[headrot]<2800 && SensorValue[headrot]<2700)
            {
                motor[head]=headrotationspeed;
            }
                motor[head]=0;
            frontscandistance[1] = SensorValue[fsonar];
            headangle+=45;
            break;

        case 90:
            while(SensorValue[headrot]<1900 && SensorValue[headrot]<1800)
            {
                motor[head]=headrotationspeed;
            }
                motor[head]=0;
            frontscandistance[2] = SensorValue[fsonar];
            headangle+=45;
            break;

            case 135:
            while(SensorValue[headrot]<1200 && SensorValue[headrot]<1100)
            {
                motor[head]=headrotationspeed;
            }
                motor[head]=0;
            frontscandistance[3] = SensorValue[fsonar];
            headangle+=45;
            break;
            case 180:
            while(SensorValue[headrot]<550 && SensorValue[headrot]<440)
            {
                motor[head]=headrotationspeed;
            }
            motor[head]=0;
            frontscandistance[4] = SensorValue[fsonar];
            headangle=0;
            break;
        }
    }
}

    task main()
    {

        startTask(frontscanner);
        }

The sonar does not scan once the head has hit each 45 degree interval respectively even though the programming seems correct. What is causing the array to store values before the while loops finish positioning the head to the proper angle?


Solution

  • To start with, your indentation is off. That isn't good practice, as it can lead to placing blocks of code inside loops unintentionally.

    To answer your question, after the first case is executed, all the other while loops are checking if the value is smaller than both your upper AND lower limits. The first case doesn't do this.

    The following is your code, but with the changes mentioned above implemented.

    #pragma config(Sensor, in1,    headrot,        sensorPotentiometer)
    #pragma config(Sensor, dgtl1,  fsonar,         sensorSONAR_inch)
    #pragma config(Sensor, dgtl3,  bsonar,         sensorSONAR_inch)
    #pragma config(Sensor, dgtl5,  steerrot,       sensorQuadEncoder)
    #pragma config(Sensor, dgtl7,  wheelrot,       sensorQuadEncoder)
    #pragma config(Motor,  port2,           head,          tmotorVex393_MC29, openLoop)
    #pragma config(Motor,  port4,           drivem,        tmotorVex393_MC29, openLoop)
    #pragma config(Motor,  port5,           steer,         tmotorVex393_MC29, openLoop)
    
    int headrotationspeed = 25;
    int frontscandistance[5]; //Array that hold each of the 5 angles at 45 degree intervals
    int headangle =0;
    task avoidance()
    {
    }
    
    task frontscanner()
    {
        //0 Degrees = 3500
        //45 Degrees = 2800
        //90 Degrees = 1900
        //135 Degrees = 1200
        //180 Degrees = 530
        while(true)
        {
            switch(headangle)
            {
            case 0:
                while(SensorValue[headrot]>3500 || SensorValue[headrot]<3400)
                {
                    motor[head]=-headrotationspeed;
                }
                motor[head]=0;
                frontscandistance[0] = SensorValue[fsonar];
                headangle+=45;
                break;
    
            case 45:
                while(SensorValue[headrot]>2800 || SensorValue[headrot]<2700)
                {
                    motor[head]=headrotationspeed;
                }
                motor[head]=0;
            frontscandistance[1] = SensorValue[fsonar];
            headangle+=45;
            break;
    
            case 90:
                while(SensorValue[headrot]>1900 || SensorValue[headrot]<1800)
                {
                    motor[head]=headrotationspeed;
                }
                motor[head]=0;
                frontscandistance[2] = SensorValue[fsonar];
                headangle+=45;
                break;
    
            case 135:
                while(SensorValue[headrot]>1200 || SensorValue[headrot]<1100)
                {
                    motor[head]=headrotationspeed;
                }
                motor[head]=0;
                frontscandistance[3] = SensorValue[fsonar];
                headangle+=45;
                break;
    
            case 180:
                while(SensorValue[headrot]>550 || SensorValue[headrot]<440)
                {
                    motor[head]=headrotationspeed;
                }
                motor[head]=0;
                frontscandistance[4] = SensorValue[fsonar];
                headangle=0;
                break;
            }
        }
    }
    
    task main()
    {
        startTask(frontscanner);
    }
    

    Also, I would like to point out that your code is written to turn the robot's head only when the measurement is IN the desired range. If any of the cases execute while the head is outside the desired range, the head won't move. If I understand correctly, you want the opposite.

    The code below contains the modification necessary to not only turn the head while it is OUT of the desired range, but also automatically turns the head in the desired direction.

    #pragma config(Sensor, in1,    headrot,        sensorPotentiometer)
    #pragma config(Sensor, dgtl1,  fsonar,         sensorSONAR_inch)
    #pragma config(Sensor, dgtl3,  bsonar,         sensorSONAR_inch)
    #pragma config(Sensor, dgtl5,  steerrot,       sensorQuadEncoder)
    #pragma config(Sensor, dgtl7,  wheelrot,       sensorQuadEncoder)
    #pragma config(Motor,  port2,           head,          tmotorVex393_MC29, openLoop)
    #pragma config(Motor,  port4,           drivem,        tmotorVex393_MC29, openLoop)
    #pragma config(Motor,  port5,           steer,         tmotorVex393_MC29, openLoop)
    
    int headrotationspeed = 25;
    int frontscandistance[5]; //Array that hold each of the 5 angles at 45 degree intervals
    int headangle =0;
    int reverse = 1 //Set this to -1 if the motor is turning in the wrong direction.
    
    task avoidance()
    {
    }
    
    task frontscanner()
    {
        //0 Degrees = 3500
        //45 Degrees = 2800
        //90 Degrees = 1900
        //135 Degrees = 1200
        //180 Degrees = 530
        while(true)
        {
            switch(headangle)
            {
            case 0:
                while(SensorValue[headrot]<3500 && SensorValue[headrot]>3400)
                {
                    motor[head]=headrotationspeed*reverse*(3500-SensorValue[headrot]/abs(3500-SensorValue[headrot]));
                }
                motor[head]=0;
                frontscandistance[0] = SensorValue[fsonar];
                headangle+=45;
                break;
    
            case 45:
                while(SensorValue[headrot]<2800 && SensorValue[headrot]>2700)
                {
                    motor[head]=headrotationspeed*reverse*(2800-SensorValue[headrot]/abs(3500-SensorValue[headrot]));
                }
                motor[head]=0;
            frontscandistance[1] = SensorValue[fsonar];
            headangle+=45;
            break;
    
            case 90:
                while(SensorValue[headrot]<1900 && SensorValue[headrot]>1800)
                {
                    motor[head]=headrotationspeed*reverse*(1900-SensorValue[headrot]/abs(3500-SensorValue[headrot]));
                }
                motor[head]=0;
                frontscandistance[2] = SensorValue[fsonar];
                headangle+=45;
                break;
    
            case 135:
                while(SensorValue[headrot]<1200 && SensorValue[headrot]>1100)
                {
                    motor[head]=headrotationspeed*reverse*(1200-SensorValue[headrot]/abs(3500-SensorValue[headrot]));
                }
                motor[head]=0;
                frontscandistance[3] = SensorValue[fsonar];
                headangle+=45;
                break;
    
            case 180:
                while(SensorValue[headrot]<550 && SensorValue[headrot]>440)
                {
                    motor[head]=headrotationspeed*reverse*(550-SensorValue[headrot]/abs(3500-SensorValue[headrot]));
                }
                motor[head]=0;
                frontscandistance[4] = SensorValue[fsonar];
                headangle=0;
                break;
            }
        }
    }
    
    task main()
    {
        startTask(frontscanner);
    }
    

    Also, I would highly recommend the VEX forums (found here: https://www.vexforum.com/) for future questions involving vex. It is more specialized towards your needs. My username is Tark1492. Feel free to message me directly if you ever get stuck on a specific question about RobotC.