View unanswered posts | View active topics It is currently Thu Nov 21, 2019 2:22 am






Reply to topic  [ 80 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next
PID Control 
Author Message
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1523
Post Re: PID Control
I think you just need to run Xander's program to calibrate the compass. Once calibrated, it is stored on the sensor and doesn't need another calibration. In theory, you don't need to recalibrate it unless you change where you mount the compass sensor on the robot (that potentially changes the surrounding magnetic field) or if you relocate your robot to another part of the country that potentially changes the magnetic direction of the "north pole". This location change is long distance (e.g. cross time zones) so it is not like you move your robot from your home to your school. Having said that about the location, it may still need recalibration if you enter a building that could alter the surrounding magnetic field (e.g. a room with large metal objects nearby). In any case, once you do a calibration, you should be good at that location.


Tue Feb 03, 2015 1:51 pm
Profile
Rookie

Joined: Sat Jan 31, 2015 1:14 am
Posts: 38
Post Re: PID Control
ok i tested it in rvw since we don't have our sensors in yet (should be here later this week) so i'm using some test worlds to go forward 53in and turn 90 degrees but it only does the forward not the turn, any idea?

Code:
 #pragma config(Hubs,  S1, HTMotor,  HTMotor,  none,     none)
#pragma config(Sensor, S1,     ,               sensorI2CMuxController)
#pragma config(Sensor, S2,     touch,          sensorTouch)
#pragma config(Sensor, S3,     light,          sensorLightActive)
#pragma config(Sensor, S4,     sonar,          sensorSONAR)
#pragma config(Motor,  mtr_S1_C1_1,     rightMotor,    tmotorTetrix, openLoop, encoder)
#pragma config(Motor,  mtr_S1_C1_2,     leftMotor,     tmotorTetrix, openLoop, reversed, encoder)
#pragma config(Motor,  mtr_S1_C2_1,     motorF,        tmotorTetrix, openLoop, encoder)
#pragma config(Motor,  mtr_S1_C2_2,     motorG,        tmotorTetrix, openLoop, reversed, encoder)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

// include files
#include "ftclib/trcdefs.h"
#include "ftclib/dbgtrace.h"
#include "ftclib/sm.h"
#include "ftclib/drive.h"
#include "ftclib/pidctrl.h"
#include "ftclib/piddrive.h"

#define ENC_KP              3.6
#define ENC_KI              0.0
#define ENC_KD              0.0
#define ENC_TOLERANCE       1.0
#define ENC_SETTLING        200

#define TURN_KP             5.0
#define TURN_KI             0.0
#define TURN_KD             0.0
#define TURN_TOLERANCE      1.0
#define TURN_SETTLING       200

#define CLICKS_PER_INCH     175.0
#define CLICKS_PER_DEGREE   100.0

#define EVTTYPE_PIDDRIVE    (EVTTYPE_NONE + 1)

DRIVE       g_drive;        //create the drive object.
PIDCTRL     g_yPidCtrl;     //create the Y PID controller
PIDCTRL     g_turnPidCtrl;  //create the turn PID controller
PIDDRIVE    g_pidDrive;     //create the PID drive object
SM          g_autoSM;       //create the autonomous state machine object

float PIDCtrlGetInput(PIDCTRL &pidCtrl)
{
    float inputValue = 0.0;

    if (IsSameReference(pidCtrl, g_yPidCtrl))
    {
        inputValue = (nMotorEncoder[leftMotor] + nMotorEncoder[rightMotor])/2.0/CLICKS_PER_INCH;
    }
    else if (IsSameReference(pidCtrl, g_turnPidCtrl))
    {
        inputValue = (nMotorEncoder[leftMotor] - nMotorEncoder[rightMotor])/2.0/CLICKS_PER_DEGREE;
    }
    return inputValue;
}

task main()
{
    // Initialize the drive object.
    DriveInit(g_drive, leftMotor, rightMotor);
    // Initialize the yPidCtrl object.
    PIDCtrlInit(g_yPidCtrl,
                ENC_KP, ENC_KI, ENC_KD,
                ENC_TOLERANCE, ENC_SETTLING);
    // Initialize the turnPidCtrl object.
    PIDCtrlInit(g_turnPidCtrl,
                TURN_KP, TURN_KI, TURN_KD,
                TURN_TOLERANCE, TURN_SETTLING);
    // Initialize the pidDrive object.
    PIDDriveInit(g_pidDrive, g_drive, g_yPidCtrl, g_turnPidCtrl);
    // Initialize the autonomous state machine and start it.
    SMInit(g_autoSM);
    SMStart(g_autoSM);

    while (true)
    {
        // Check if state machine is ready.
        if (SMIsReady(g_autoSM))
        {
            int currState = SMGetState(g_autoSM);
            switch (currState)
            {
                case SMSTATE_STARTED:
                    // Drive forward for 36 inches.
                    PIDDriveSetTarget(g_pidDrive,
                                      53.0,
                                      0.0,
                                      false,
                                      &g_autoSM,
                                      EVTTYPE_PIDDRIVE);
                    // Tell state machine to wait until done.
                    SMAddWaitEvent(g_autoSM, EVTTYPE_PIDDRIVE);
                    // Tell state machine to go to next state when done.
                    SMWaitEvents(g_autoSM, currState + 1);
                    break;

                case SMSTATE_STARTED + 1:
                    // Turn right 90 degrees.
                    PIDDriveSetTarget(g_pidDrive,
                                      0.0,
                                      90.0,
                                      false,
                                      &g_autoSM,
                                      EVTTYPE_PIDDRIVE);
                    // Tell state machine to wait until done.
                    SMAddWaitEvent(g_autoSM, EVTTYPE_PIDDRIVE);
                    // Tell state machine to go to next state when done.
                    SMWaitEvents(g_autoSM, currState + 1);
                    break;

                default:
                    // We are done, stop the state machine.
                    SMStop(g_autoSM);
                    break;
            }
        }
        //
        // Execute all periodic tasks.
        //
        PIDDriveTask(g_pidDrive);
        DriveTask(g_drive);
        wait1Msec(20);
    }


and about the compass, thank you i'll try that :D

EDIT: i took the gyro sample and switched it with compass and it seems to work however i'm not sure i'm tuning it right, i put 90 degrees and tuned compass ki and clicks per inch but it still seems to be off, which one am i supposed to tune for that? and it's off by just a little or alot every other time i run it...like the degree tolerance is set too high, or do you think i should calibrate it in rvw, not sure how to do it in rvw though...maybe could it be because none of the preset robots have a compass and i just switched a port to be compass even though it isn't i guess??

Code:
 #pragma config(Hubs,  S1, HTMotor,  HTMotor,  none,     none)
#pragma config(Sensor, S2,     irSeeker,       sensorHiTechnicIRSeeker1200)
#pragma config(Sensor, S3,     compassSensor,  sensorI2CHiTechnicCompass)
#pragma config(Motor,  mtr_S1_C1_1,     rightMotor,    tmotorTetrix, openLoop, encoder)
#pragma config(Motor,  mtr_S1_C1_2,     leftMotor,     tmotorTetrix, openLoop, reversed, encoder)
#pragma config(Motor,  mtr_S1_C2_1,     motorF,        tmotorTetrix, openLoop, encoder)
#pragma config(Motor,  mtr_S1_C2_2,     motorG,        tmotorTetrix, openLoop, reversed, encoder)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

// include files
#include "ftclib/trcdefs.h"
#include "ftclib/dbgtrace.h"
#include "ftclib/sm.h"
#include "ftclib/compass.h"
#include "ftclib/drive.h"
#include "ftclib/pidctrl.h"
#include "ftclib/piddrive.h"

#define ENC_KP              3.6
#define ENC_KI              0.0
#define ENC_KD              0.0

#define ENC_TOLERANCE       1.0
#define ENC_SETTLING        200

#define COMP_KP             0.25
#define COMP_KI             0.0
#define COMP_KD             0.0
#define COMP_TOLERANCE      1.0
#define COMP_SETTLING       200

#define CLICKS_PER_INCH     75.55

COMPASS       g_compass;         //create the compass object.
DRIVE       g_drive;        //create the drive object.
PIDCTRL     g_yPidCtrl;     //create the Y PID controller
PIDCTRL     g_turnPidCtrl;  //create the turn PID controller
PIDDRIVE    g_pidDrive;     //create the PID drive object

float PIDCtrlGetInput(PIDCTRL &pidCtrl)
{
    float inputValue = 0.0;

    if (IsSameReference(pidCtrl, g_yPidCtrl))
    {
        inputValue = (nMotorEncoder[leftMotor] + nMotorEncoder[rightMotor])/2.0/CLICKS_PER_INCH;
    }
    else if (IsSameReference(pidCtrl, g_turnPidCtrl))
    {
        inputValue = CompassGetHeading(g_compass);
    }
    return inputValue;
}

task main()
{
    CompassInit(g_compass, compassSensor);   //initialize compass object.
    DriveInit(g_drive, leftMotor, rightMotor);  //initialize drive object
    PIDCtrlInit(g_yPidCtrl,         //initialize yPidCtrl object
                ENC_KP, ENC_KI, ENC_KD,
                ENC_TOLERANCE, ENC_SETTLING);
    PIDCtrlInit(g_turnPidCtrl,
                COMP_KP, COMP_KI, COMP_KD,
                COMP_TOLERANCE, COMP_SETTLING);
    PIDDriveInit(g_pidDrive, g_drive, g_yPidCtrl, g_turnPidCtrl);

    PIDDriveSetTarget(g_pidDrive, 0.0, 90.0);

    while (true)
    {
        CompassTask(g_compass);
        PIDDriveTask(g_pidDrive);
        DriveTask(g_drive);
    }
}


Last edited by BTB1337 on Tue Feb 03, 2015 3:51 pm, edited 1 time in total.



Tue Feb 03, 2015 2:03 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1523
Post Re: PID Control
BTB1337 wrote:
ok i tested it in rvw since we don't have our sensors in yet (should be here later this week) so i'm using some test worlds to go forward 53in and turn 90 degrees but it only does the forward not the turn, any idea?

and about the compass, thank you i'll try that :D

I haven't been playing with Virtual World for a long time so I just loaded up Cascade Effect world and pasted my code into the ScissorBot (made some adjustment to the code for the scissorbot). Virtual World has changed significantly since I last played with it, so I don't know how to make it work. It just showed me a square window in metallic gray with 3 diagonal lines on the upper left corner. It didn't show me any start button or anything and nothing was moving.
In any case, since I can't verify anything in virtual world, I can only guess what happened. Since you have changed the distance to 53.0 inches, I assume you have adjusted the CLICKS_PER_INCH correctly. How about CLICKS_PER_DEGREE? Did the robot go 53.0 inches as expected? If so, you mentioned that it did not turn. It doesn't look like you have changed KP at all. I am not familiar with the physics of the virtual world but if it simulates the physical world close enough, it is possible that the KP for turn is too low that the robot was trying to turn but wasn't able to. In any case, is there any way to display things on the "Remote LCD screen" in the Virtual World? If so, you need to display some debug info on it. The first thing I would want to see is the value of currState. For example:
Code:
    while (true)
    {
        nxtDisplayTextLine(0, "state=%d", SMGetState(g_autoSM));
        PIDCtrlDisplayInfo(1, g_yPidCtrl);
        PIDCtrlDisplayInfo(3, g_turnPidCtrl);
        // Check if state machine is ready.
        if (SMIsReady(g_autoSM))
        {
            int currState = SMGetState(g_autoSM);
            switch (currState)
            {
                case SMSTATE_STARTED:

This will tell you if the state machine was stuck at SMSTATE_STARTED or it has moved on to the next state. If it was stuck at SMSTATE_STARTED, it means PID control has not completed the target of 53.0 inches. This could happen if ENC_KP is too low and the robot was not within the tolerance of the 53.0 inch target and did not have enough power to get there. In any case, the library also contains some debugging tools such as PIDCtrlDisplayInfo (see sample code above). That will display some vital info about the PID controller. T is target, E is error, I is current input value (i.e. robot position in inches or degrees), O is the output power to the motor. From this info, you should be able to tell why the robot is not moving.


Tue Feb 03, 2015 3:47 pm
Profile
Rookie

Joined: Sat Jan 31, 2015 1:14 am
Posts: 38
Post Re: PID Control
ok thanks i'll try it, i also updated my previous post with more code from another program using the gyro sample code replaced with compass

EDIT: Ok so i got the nxt to display it and i was able to adjust the enc_kp appropriately however, is there a proper way to adjust the clicks_per_degree and clicks_per_inch? i just kinda guessed on those until it hit the right spot

also, the turning, the T says 90.0 but the I says 88.0 and it shows that the robot actually turned to far?


Tue Feb 03, 2015 3:54 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1523
Post Re: PID Control
BTB1337 wrote:
i took the gyro sample and switched it with compass and it seems to work however i'm not sure i'm tuning it right, i put 90 degrees and tuned compass ki and clicks per inch but it still seems to be off, which one am i supposed to tune for that? and it's off by just a little or alot every other time i run it...like the degree tolerance is set too high, or do you think i should calibrate it in rvw, not sure how to do it in rvw though...maybe could it be because none of the preset robots have a compass and i just switched a port to be compass even though it isn't i guess??

Compass is different from gyro. Gyro is a relative heading device but compass is an absolute heading device. So with a gyro, when you say turn right 90 degrees, you are actually saying turn right 90 degree from my current heading. So if your robot is already at 45 degrees since start of the match (heading NE assuming the robot facing N at start of match), you will turn to 45+90 = 135 (pointing to SE). Whereas with the compass, the start heading of your robot is not necessary always 0 (i.e. North). It depends on the competition field orientation. So if you want to turn 90 degree from your starting position, you need to say GetHeading + 90. Having said that, the library does differentiate between relative and absolute setPoints. So internally, it is already doing GetInput + degree-to-turn, if that's what you want. But to take advantage of the absolute heading that the compass offers, you need to tell the PID controller that the compass is an absolute device by using the PIDCTRLO_ABS_SETPT option.
BTW, I don't think you need to calibrate the compass in the Virtual World. The magnetic field in the Virtual World is PERFECT :bigthumb: Only real physical world needs calibration. Also, compass doesn't have CLICKS_PER_DEGREE (clicks is a property of encoder). Compass is already returning in the unit of degrees. You can just delete the CLICKS_PER_DEGREE constant.
I am not familiar with the current state of Virtual World. It used to be that you cannot change anything on the "provided bot". If that's still true then you cannot switch to use a compass if it was not already there. BTW, which virtual bot are you using? Would you also tell me how to run Virtual World nowadays so I could debug it on my end too? I switched to "Compile to virtual world" and selected the "Cascade Effect" field, but when I did a compile and download, all it does is popping up a gray square window with 3 diagonal lines on the top left corner. That's it, there is no control, no robot, no recognizable field elements. I thought it may be "zoomed in" but there is no control for me to "zoom out" if that's the case.


Tue Feb 03, 2015 4:22 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1523
Post Re: PID Control
BTB1337 wrote:
ok thanks i'll try it, i also updated my previous post with more code from another program using the gyro sample code replaced with compass

EDIT: Ok so i got the nxt to display it and i was able to adjust the enc_kp appropriately however, is there a proper way to adjust the clicks_per_degree and clicks_per_inch? i just kinda guessed on those until it hit the right spot

also, the turning, the T says 90.0 but the I says 88.0 and it shows that the robot actually turned to far?

Regarding adjusting CLICKS_PER_INCH in the real world, one would check the reported distance against the tape measured distance but this is kind of hard in the virtual world. If you are using the Cascade Effect field, it has 2 ft square foam tiles. In the past, the Virtual World shows the square tiles. So if you can doing a top view, you can have the robot go forward 8 ft, it is supposed to cross 4 tiles.
Regarding CLICKS_PER_DEGREE, like I said in another reply, compass doesn't need this.
Regarding the turn, if T (target) is 90 and I (input) said 88. It means Kp needs a bigger value. Since tolerance is 1.0 degree, it is acceptable to have I stopping between 89.0 and 91.0. If you can't reach that range, Kp is too weak.
Please note that even if you tune the K constants perfectly in Virtual World, you need to re-tune it on your real robot in the real world.


Tue Feb 03, 2015 5:33 pm
Profile
Rookie

Joined: Sat Jan 31, 2015 1:14 am
Posts: 38
Post Re: PID Control
ok thanks! and for virtual world I am using RobotC 4 and the newest version of rvw, make sure the cascade effect world is working properly, i'm using the Curriculum Companion 4.2.7 world, under "Robot" i chose Tetrix Ranger and under "movement" i chose "Line Painter Challenge" to get a good idea that it truely is going straight, for that I'm not using the compass i'm just using general encoders for turning

Code:
 #pragma config(Hubs,  S1, HTMotor,  HTMotor,  none,     none)
#pragma config(Sensor, S1,     ,               sensorI2CMuxController)
#pragma config(Sensor, S2,     touch,          sensorTouch)
#pragma config(Sensor, S3,     light,          sensorLightActive)
#pragma config(Sensor, S4,     sonar,          sensorSONAR)
#pragma config(Motor,  mtr_S1_C1_1,     rightMotor,    tmotorTetrix, openLoop, encoder)
#pragma config(Motor,  mtr_S1_C1_2,     leftMotor,     tmotorTetrix, openLoop, reversed, encoder)
#pragma config(Motor,  mtr_S1_C2_1,     motorF,        tmotorTetrix, openLoop, encoder)
#pragma config(Motor,  mtr_S1_C2_2,     motorG,        tmotorTetrix, openLoop, reversed, encoder)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

// include files
#include "ftclib/trcdefs.h"
#include "ftclib/dbgtrace.h"
#include "ftclib/sm.h"
#include "ftclib/drive.h"
#include "ftclib/pidctrl.h"
#include "ftclib/piddrive.h"

#define ENC_KP              6.0
#define ENC_KI              0.0
#define ENC_KD              0.0
#define ENC_TOLERANCE       1.0
#define ENC_SETTLING        200

#define TURN_KP             4.5
#define TURN_KI             0.0
#define TURN_KD             0.0
#define TURN_TOLERANCE      0.5
#define TURN_SETTLING       200

#define CLICKS_PER_INCH     170.0
#define CLICKS_PER_DEGREE   18.0

#define EVTTYPE_PIDDRIVE    (EVTTYPE_NONE + 1)

DRIVE       g_drive;        //create the drive object.
PIDCTRL     g_yPidCtrl;     //create the Y PID controller
PIDCTRL     g_turnPidCtrl;  //create the turn PID controller
PIDDRIVE    g_pidDrive;     //create the PID drive object
SM          g_autoSM;       //create the autonomous state machine object

float PIDCtrlGetInput(PIDCTRL &pidCtrl)
{
    float inputValue = 0.0;

    if (IsSameReference(pidCtrl, g_yPidCtrl))
    {
        inputValue = (nMotorEncoder[leftMotor] + nMotorEncoder[rightMotor])/2.0/CLICKS_PER_INCH;
    }
    else if (IsSameReference(pidCtrl, g_turnPidCtrl))
    {
        inputValue = (nMotorEncoder[leftMotor] - nMotorEncoder[rightMotor])/2.0/CLICKS_PER_DEGREE;
    }
    return inputValue;
}

task main()
{
    // Initialize the drive object.
    DriveInit(g_drive, leftMotor, rightMotor);
    // Initialize the yPidCtrl object.
    PIDCtrlInit(g_yPidCtrl,
                ENC_KP, ENC_KI, ENC_KD,
                ENC_TOLERANCE, ENC_SETTLING);
    // Initialize the turnPidCtrl object.
    PIDCtrlInit(g_turnPidCtrl,
                TURN_KP, TURN_KI, TURN_KD,
                TURN_TOLERANCE, TURN_SETTLING);
    // Initialize the pidDrive object.
    PIDDriveInit(g_pidDrive, g_drive, g_yPidCtrl, g_turnPidCtrl);
    // Initialize the autonomous state machine and start it.
    SMInit(g_autoSM);
    SMStart(g_autoSM);

    while (true)
    {
          nxtDisplayTextLine(0, "state=%d", SMGetState(g_autoSM));
        PIDCtrlDisplayInfo(1, g_yPidCtrl);
        PIDCtrlDisplayInfo(3, g_turnPidCtrl);
        // Check if state machine is ready.
        if (SMIsReady(g_autoSM))
        {
            int currState = SMGetState(g_autoSM);
            switch (currState)
            {
                case SMSTATE_STARTED:
                    // Drive forward for 36 inches.
                    PIDDriveSetTarget(g_pidDrive,
                                      56.0,
                                      0.0,
                                      false,
                                      &g_autoSM,
                                      EVTTYPE_PIDDRIVE);
                    // Tell state machine to wait until done.
                    SMAddWaitEvent(g_autoSM, EVTTYPE_PIDDRIVE);
                    // Tell state machine to go to next state when done.
                    SMWaitEvents(g_autoSM, currState + 1);
                    break;

                case SMSTATE_STARTED + 1:
                    // Turn right 90 degrees.
                    PIDDriveSetTarget(g_pidDrive,
                                      0.0,
                                      90.0,
                                      false,
                                      &g_autoSM,
                                      EVTTYPE_PIDDRIVE);
                    // Tell state machine to wait until done.
                    SMAddWaitEvent(g_autoSM, EVTTYPE_PIDDRIVE);
                    // Tell state machine to go to next state when done.
                    SMWaitEvents(g_autoSM, currState + 1);
                    break;

                case SMSTATE_STARTED + 2:
                      // Go forward 43 inches.
                      PIDDriveSetTarget(g_pidDrive,
                                                 43.0,
                                                 0.0,
                                                 false,
                                                 &g_autoSM,
                                                 EVTTYPE_PIDDRIVE);
                      // Tell state machine to wait until done.
                      SMAddWaitEvent(g_autoSM, EVTTYPE_PIDDRIVE);
                      // Tell state machine to go to next state when done.
                      SMWaitEvents(g_autoSM, currState + 1);
                      break;
                   
                default:
                    // We are done, stop the state machine.
                    SMStop(g_autoSM);
                    break;
            }
        }
        //
        // Execute all periodic tasks.
        //
        PIDDriveTask(g_pidDrive);
        DriveTask(g_drive);
        wait1Msec(20);
    }


this code seems to work perfectly going straight and making a 90 degree right turn and go to the end

i'm currently working on implementing the compass sensor into that program


Tue Feb 03, 2015 5:59 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1523
Post Re: PID Control
BTB1337 wrote:
ok thanks! and for virtual world I am using RobotC 4 and the newest version of rvw, make sure the cascade effect world is working properly, i'm using the Curriculum Companion 4.2.7 world, under "Robot" i chose Tetrix Ranger and under "movement" i chose "Line Painter Challenge" to get a good idea that it truely is going straight, for that I'm not using the compass i'm just using general encoders for turning

this code seems to work perfectly going straight and making a 90 degree right turn and go to the end

i'm currently working on implementing the compass sensor into that program

If you are using the encoders for turning, then first you need to tune KP such that T (target) and I (input) should be within tolerance. Then you set Target to 90 degree and visually look at the robot in virtual world to make sure it's indeed 90. If not, adjust CLICKS_PER_DEGREE to correct.

Regarding PIDCTRLO_ABS_SETPT, this is an option of the PIDCtrl.h module (hint: the prefix is PIDCTRLO_ meaning it is a PIDCtrl option). You can set it when initializing PIDCtrl such as:
Code:
 PIDCtrlInit(g_turnPidCtrl,
             TURN_KP, TURN_KI, TURN_KD,
             TURN_TOLERANCE, TURN_SETTLING,
             PIDCTRLO_ABS_SETPT);


Tue Feb 03, 2015 6:16 pm
Profile
Rookie

Joined: Sat Jan 31, 2015 1:14 am
Posts: 38
Post Re: PID Control
Thanks! and i implemented it with the compass and it seems you were right that the sensor can't be changed to a compass so right now it just spins in circles and the t and i don't change on the nxt so i'll wait for them to come in. also, i know tuning can be a pain in the butt is there a easy way of doing it or do you have to run a program and adjust it accordingly until you run it and it goes the proper distance or the right angle every time? if you have to run it over and over again then that would get annoying really fast


Tue Feb 03, 2015 8:39 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1523
Post Re: PID Control
BTB1337 wrote:
Thanks! and i implemented it with the compass and it seems you were right that the sensor can't be changed to a compass so right now it just spins in circles and the t and i don't change on the nxt so i'll wait for them to come in. also, i know tuning can be a pain in the butt is there a easy way of doing it or do you have to run a program and adjust it accordingly until you run it and it goes the proper distance or the right angle every time? if you have to run it over and over again then that would get annoying really fast

Are you talking about calibrating the compass or tuning the PID? Tuning PID will need some time but not too awful. Calibrating the compass could be a little tricky. Imagine arriving at the competition site, you need to do a compass 360 calibration on the field and possibly both fields just to make sure there is no big metal object near either field. That's not too bad but if you are going to do ABS_SETPT mode, then you need to determine the orientation of the field and hoping the other field has identical orientation. Having said that, you can take care of the difference using code if you are careful about it. So just want to make you aware of the potential issues. Our team has compass sensors too but we never use them in real competition for these reasons. I would be really interested in hearing your experience with the compass sensor. We always want to revisit the compass sensor off season but never got a chance to do it.


Tue Feb 03, 2015 9:41 pm
Profile
Rookie

Joined: Sat Jan 31, 2015 1:14 am
Posts: 38
Post Re: PID Control
i'm talking about tuning the PID, any tips to make it not so bad? haha and yikes compass calibration seems difficult and unfortunately i'm not that advanced with programming (which is why i'm on the forums) so it will definately take me awhile to figure all this out, unfortunately, i've passed up our coach and our former lead programmer's robotc skill with pid and stuff so i don't have anyone for guidance.

would gyro's be any easier? Maybe we'll try and order one and experiment with compass sensors during spare time... if we do go with the compass and get it to work i'll be sure to share my experience with it.


Tue Feb 03, 2015 10:34 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1523
Post Re: PID Control
If you are just doing proportional only PID (i.e. with Ki and Kd zero), that isn't too bad. I think gyro is more reliable in general. We never had any trouble with it.


Tue Feb 03, 2015 10:57 pm
Profile
Rookie

Joined: Sat Jan 31, 2015 1:14 am
Posts: 38
Post Re: PID Control
oh ok thanks! another question, i'm trying to create a toggle before each autonomous program to toggle waitForStart() to be true or false in Competition Mode (waitForStart() = true) or Testing Mode (waitForStart() = false) but it seems to completely skip my while statement...i'm not sure if i'm even doing this right haha, couldn't find anywhere what button the orange enter button is, is it 1 or 0? the idea is you run the program and you can select Competition mode or Testing mode, if nothing is pushed within 10sec then default to waitForStart() = true

Code:
 #include "JoystickDriver.c"  //Include file to "handle" the Bluetooth messages.

int on;

void initializeRobot()
{
  // Place code here to sinitialize servos to starting positions.
  // Sensors are automatically configured and setup by ROBOTC. They may need a brief time to stabilize.

  return;
}

//bool mode = waitForStart();

#define mode   waitForStart()

task main()
{
  initializeRobot();
   
  on = 0;
 
  while(on = 0)
  {
      if(nNxtButtonPressed == 1)
      {
        mode == false;
        
        displayBigTextLine(2, "Test");
        displayBigTextLine(5, "Mode");
        
        wait10Msec(10000);
        
        on = 1;
        
      }
      else
      {
         mode == true;
         
         displayBigTextLine(2, "Competition");
         displayBigTextLine(4, "   Mode");
         
         wait10Msec(10000);
         
         on = 1;
      }
   }

  //waitForStart(); // Wait for the beginning of autonomous phase.

  motor[leftMotor] = 100;
  motor[rightMotor] = 100;
 
  wait10Msec(300);
 
  motor[leftMotor] = 0;
  motor[rightMotor] = 0;
 
}


Wed Feb 04, 2015 10:02 am
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1523
Post Re: PID Control
BTB1337 wrote:
oh ok thanks! another question, i'm trying to create a toggle before each autonomous program to toggle waitForStart() to be true or false in Competition Mode (waitForStart() = true) or Testing Mode (waitForStart() = false) but it seems to completely skip my while statement...i'm not sure if i'm even doing this right haha, couldn't find anywhere what button the orange enter button is, is it 1 or 0? the idea is you run the program and you can select Competition mode or Testing mode, if nothing is pushed within 10sec then default to waitForStart() = true

There are many things wrong in that code. For starter, the statement "while (on = 0)", that's an assignment statement in the while condition. Basically, you keep assigning 0 to the variable on. Secondly, you define a macro "mode" to be substituted by waitForStart(). That makes your statement "mode = false" be translated to "waitForStart() = false". This is completely illegal. You can't invoke a function on the left side of an assignment statement. Even if you fixed those problems, I don't think your logic works anyway. Since you are using our library, why don't you do this instead.
Code:
#include "JoystickDriver.c"  //Include file to "handle" the Bluetooth messages.
#include "ftclib/trcdefs.h"
#include "ftclib/dbgtrace.h"
#include "ftclib/menu.h"

MENU    g_competitionMenu;

void initializeRobot()
{
  // Place code here to sinitialize servos to starting positions.
  // Sensors are automatically configured and setup by ROBOTC. They may need a brief time to stabilize.
  MenuInit(g_competitionMenu, "Competition mode:");
  MenuAddChoice(g_competitionMenu, "No", 0);
  MenuAddChoice(g_competitionMenu, "Yes", 1);
  return;
}

task main()
{
  initializeRobot();
  if (MenuGetChoice(g_competitionMenu) == 1)
  {
    waitForStart(); // Wait for the beginning of autonomous phase.
  }
  motor[leftMotor] = 100;
  motor[rightMotor] = 100;
 
  wait10Msec(300);
 
  motor[leftMotor] = 0;
  motor[rightMotor] = 0;
 
}


Wed Feb 04, 2015 5:32 pm
Profile
Rookie

Joined: Sat Jan 31, 2015 1:14 am
Posts: 38
Post Re: PID Control
Oh wow ok that's simple haha, much simpler than I just figured out a few hours ago before reading this haha, here's what i figured out:

Code:
 #include "JoystickDriver.c"  //Include file to "handle" the Bluetooth messages.

int timeLeft;
int runTime;

void initializeRobot()
{
  // Place code here to sinitialize servos to starting positions.
  // Sensors are automatically configured and setup by ROBOTC. They may need a brief time to stabilize.

  return;
}

void runMode()
{
   while(true)
   {
      // Calculate runTime
     // Calculate the Time left to engage test mode
      runTime = nPgmTime*.001;
      timeLeft = abs(runTime-10);

      // display instuctions
      displayTextLine(1, "   Press Enter");
      displayTextLine(3, "    to Engage");
      displayTextLine(5, "    Test Mode");
      displayTextLine(7, "  Time Left: %d", timeLeft);

      // if statement to switch waitForStart()
      if(nPgmTime <= 10000 && nNxtButtonPressed == 3)
      {
         eraseDisplay();
          displayTextLine(2, "   Test");
          displayTextLine(4, "   Mode");

          sleep(5000);

         return;
      }
      else if(nPgmTime > 10000)
      {
         eraseDisplay();
         displayTextLine(2, "   Competition");
         displayTextLine(4, "      Mode");

         waitForStart();
         
         return;
      }
   }
}

task main()
{
   initializeRobot();

  runMode();

  motor[leftMotor] = 100;
  motor[rightMotor] = 100;

  sleep(3000);

  motor[leftMotor] = 0;
  motor[rightMotor] = 0;

}


also i was thinking, when you go down the ramp even with pid, you always end up getting orientated wrong, is there a way with the compass say that when you are at the bottom of the ramp rotate back to your origional heading? i thought through it and to my knowledge couldn't find a logical way to make it work.


Wed Feb 04, 2015 11:10 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 80 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next

Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  



Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.