View unanswered posts | View active topics It is currently Tue Jul 29, 2014 11:50 pm






Reply to topic  [ 2 posts ] 
NXTSegway 
Author Message
Rookie
User avatar

Joined: Wed Jul 02, 2008 8:45 pm
Posts: 3
Location: Washington
Post NXTSegway
I know that a lot of people have been creating these self-balancing robots, but I thought that for my first ROBOTC project I would try and make one of my own. I am currently using a light sensor to calculate the direction of error and it works alright, but there is a lot of room for improvement. This is my first revision, and if you have any tips or suggestions, please let me know. I have videos of both versions at my new blog, http://www.madrobotics.blogspot.com, and you can leave comments there as well. I posted an uncommented version here; my commented one is attached at my blog and only looks good in ROBOTC's IDE...when I pasted it here it looked nasty...
Code:
const tSensors LightSensor          = (tSensors) S3;   //sensorLightActive  //*!!!!*//
//*!!CLICK to edit 'wizard' created sensor & motor configuration.                !!*//

//NXTSegway_Rev_01.c -- Using the NXT's raw light sensor values to more precisely calculate error
//and compensate for it using the motors to achieve and sustain stability

int midValue = 0;
int minValue = 0;
int maxValue = 0;
task main()
{

   nSyncedMotors = synchAC;

   bFloatDuringInactiveMotorPWM = false;

   while (nNxtButtonPressed == -1)
   {
   }

   midValue = SensorRaw[LightSensor];

   wait1Msec(1000);

   while (nNxtButtonPressed == -1)
   {
   }

   minValue = SensorRaw[LightSensor];

   wait1Msec(1000);

   while (nNxtButtonPressed == -1)
   {
   }

   maxValue = SensorRaw[LightSensor];

   wait1Msec(1000);

   if (maxValue < midValue && minValue < midValue)
   {
      PlaySound(soundDownwardTones);
      if (bSoundActive == true)
      {
      }
      nxtDisplayCenteredTextLine(4, "Choose somewhere else");
   }

   if (maxValue > midValue && minValue > midValue)
   {
      PlaySound(soundDownwardTones);
      if (bSoundActive == true)
      {
      }
      nxtDisplayCenteredTextLine(4, "Choose somewhere else");
   }

   if (maxValue > minValue)
   {
      bMotorReflected[motorA] = true;
      bMotorReflected[motorC] = true;
   }

   while (nNxtButtonPressed == -1)
   {
   }

   wait1Msec(3000);

   while (SensorRaw[LightSensor] == midValue)
   {
   }

   while (true)
   {
      if (SensorRaw[LightSensor] < midValue)
      {
         while (SensorRaw[LightSensor] < midValue)
         {
            motor[motorA] = 100;
         }
      }
      else
      {
         while (SensorRaw[LightSensor] > midValue)
         {
            motor[motorA] = -100;
         }
      }
   }
}

//Results -- Very jerky, but stays up for 4-5 seconds at a time and the error does not
//continuously escalate to extremes that are unable to be compensated for like revision 0;
//much quicker response time


Mon Jul 07, 2008 12:21 am
Profile
Rookie
User avatar

Joined: Wed Jul 02, 2008 8:45 pm
Posts: 3
Location: Washington
Post NXTSegway Revision 0.2 - Dynamic Recalibration
I have revised my NXTSegway program and have included a method of recalculating the target light value of the light sensor. The program stores an extreme, averages it with the previous extreme, and uses the average as the new target light value. This way, slight error can be completely overcome. I have a video at my blog http://madrobotics.blogspot.com that you can check out. Also, please give me some feedback here or at my blog...this is my first week using ROBOTC and I am trying to improve. I fixed my comments so I can upload the commented code here now...
Code:
//*!!Sensor,    S3,          LightSensor, sensorLightActive,      ,              !!*//
//*!!                                                                            !!*//
//*!!Start automatically generated configuration code.                           !!*//
const tSensors LightSensor          = (tSensors) S3;   //sensorLightActive  //*!!!!*//
//*!!CLICK to edit 'wizard' created sensor & motor configuration.                !!*//

//NXTSegway_Rev_02.c -- Using the NXT's raw light sensor values to more precisely calculate error
//and compensate for it using the motors and dynamic recalibration to stabilize itself

int midValue = 0;      //Initial vertical raw value
int minValue = 0;      //Initial tilted-back raw value
int maxValue = 0;      //Initial tilted-forward raw value
int extrmValue1 = 0;      //Stores extremes
int extrmValue2 = 0;      //Stores extremes
int avgValue = 0;      //Dynamically-adjusted vertical value
int n = 0;      //Counter

task main()
{

   nSyncedMotors = synchAC;      //synchs both motors

   bFloatDuringInactiveMotorPWM = false;      //Motors brake when inactive

   while (nNxtButtonPressed == -1)      //Waits for a button press
   {
   }

   midValue = SensorRaw[LightSensor];      //Reads and stores the vertical raw light data

   wait1Msec(1000);      //nNXTButtonPressed can reset to -1

   while (nNxtButtonPressed == -1)      //Waits for a button press
   {
   }

   minValue = SensorRaw[LightSensor];      //Reads and stores the tilted raw light data

   wait1Msec(1000);      //nNXTButtonPressed can reset to -1

   while (nNxtButtonPressed == -1)      //Waits for button press
   {
   }

   maxValue = SensorRaw[LightSensor];      //Reads and stores the tilted raw light data

   wait1Msec(1000);      //nNXTButtonPressed can reset to -1

   if (maxValue < midValue && minValue < midValue)      //Erratic light patterns handler
   {
      PlaySound(soundDownwardTones);
      if (bSoundActive == true)
      {
      }
      nxtDisplayCenteredTextLine(4, "Choose somewhere else");
   }

   if (maxValue > midValue && minValue > midValue)      //Erratic light patterns handler
   {
      PlaySound(soundDownwardTones);
      if (bSoundActive == true)
      {
      }
      nxtDisplayCenteredTextLine(4, "Choose somewhere else");
   }

   if (maxValue > minValue)      //Reverses motors depending on tilt direction
   {
      bMotorReflected[motorA] = true;
      bMotorReflected[motorC] = true;
   }

   while (nNxtButtonPressed == -1)      //Waits for a button press
   {
   }

   wait1Msec(3000);      //Waits three seconds before beginning

   avgValue = midValue;      //Sets the avgValue to the vertical value

   while (SensorRaw[LightSensor] == avgValue)      //If the robot is vertical, do nothing
   {
   }

   while (true)      //Forever
   {
      if (SensorRaw[LightSensor] < avgValue)      //If tilting
      {
         n = n + 1;      //Increment n

         extrmValue1 = SensorRaw[LightSensor];      //Store next extreme

         if (n == 1)      //If first loop...
         {
            extrmValue2 = avgValue - (extrmValue1 - avgValue);      //...sets second extreme to offset the first one
         }

         while (SensorRaw[LightSensor] < avgValue)      //While not vertical...
         {
            motor[motorA] = 100;      //...Power both motors until vertical
         }

         avgValue = (extrmValue2 + extrmValue1)/2;      //Find average of last two extremes

         extrmValue2 = SensorRaw[LightSensor];      //Store next extreme

         while (SensorRaw[LightSensor] > avgValue)      //While not vertical...
         {
            motor[motorA] = -100;      //...Power both motors until vertical
         }

         avgValue = (extrmValue1 + extrmValue2)/2;      //Finds average of last two extremes
      }
      else      //If tilting the other way
      {
         n = n + 1;      //Increment n

         extrmValue1 = SensorRaw[LightSensor];      //Store next extreme

         if (n == 1)      //If first loop...
         {
            extrmValue2 = avgValue - (extrmValue1 - avgValue);      //...sets second extreme to offset the first one
         }

         while (SensorRaw[LightSensor] > avgValue)      //While not vertical...
         {
            motor[motorA] = -100;      //...power both motors until vertical
         }

         avgValue = (extrmValue2 + extrmValue1)/2;      //finds average of last two extremes (new avgValue)

         extrmValue2 = SensorRaw[LightSensor];      //Store next extreme

         while (SensorRaw[LightSensor] < avgValue)      //While not vertical...
         {
            motor[motorA] = 100;      //...Power both motors until vertical
         }

         avgValue = (extrmValue1 + extrmValue2)/2;      //Finds average of last two extremes
      }
   }
}

//Results: Stays vertical independently for about 11 seconds on the right surface
//Problems: With current implementation of dynamic recalibration, significant error cannot be overcome


Tue Jul 08, 2008 1:06 am
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 2 posts ] 

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.