Modifications

Sauter à la navigation Sauter à la recherche
8 178 octets ajoutés ,  30 avril 2018 à 19:39
Ligne 124 : Ligne 124 :  
* ''numSamplesPerSensor'' indicates the number of 10-bit analog samples to average per channel (per sensor) for each reading. The total number of analog-to-digital conversions performed will be equal to numSensors times numSamplesPerSensor. Increasing this parameter increases noise suppression at the cost of sample rate. This parameter must not exceed 64. Recommended value: 4.
 
* ''numSamplesPerSensor'' indicates the number of 10-bit analog samples to average per channel (per sensor) for each reading. The total number of analog-to-digital conversions performed will be equal to numSensors times numSamplesPerSensor. Increasing this parameter increases noise suppression at the cost of sample rate. This parameter must not exceed 64. Recommended value: 4.
 
* ''emitterPin'' is the Arduino digital pin that controls whether the IR LEDs are on or off. This pin is optional and only exists on the 8A and 8RC QTR sensor arrays. If a valid pin is specified, the emitters will only be turned on during a reading. If the value QTR_NO_EMITTER_PIN (255) is used, you can leave the emitter pin disconnected and the IR emitters will always be on.
 
* ''emitterPin'' is the Arduino digital pin that controls whether the IR LEDs are on or off. This pin is optional and only exists on the 8A and 8RC QTR sensor arrays. If a valid pin is specified, the emitters will only be turned on during a reading. If the value QTR_NO_EMITTER_PIN (255) is used, you can leave the emitter pin disconnected and the IR emitters will always be on.
 +
 +
== Note d'usage ==
 +
=== Calibration ===
 +
This library allows you to use the '''calibrate()''' method to easily calibrate your sensors for the particular conditions it will encounter. Calibrating your sensors can lead to substantially more reliable sensor readings, which in turn can help simplify your code since. As such, we recommend you build a calibration phase into your application’s initialization routine. This can be as simple as a fixed duration over which you repeated call the '''calibrate()''' method. During this calibration phase, you will need to expose each of your reflectance sensors to the lightest and darkest readings they will encounter. For example, if you have made a line follower, you will want to slide it across the line during the calibration phase so the each sensor can get a reading of how dark the line is and how light the ground is. A sample calibration routine would be:
 +
 +
<syntaxhighlight lang="C">#include <QTRSensors.h>
 +
 +
// create an object for your type of sensor (RC or Analog)
 +
// in this example we have three sensors on analog inputs 0 - 2, a.k.a. digital pins 14 - 16
 +
QTRSensorsRC qtr((char[]) {14, 15, 16}, 3);
 +
// QTRSensorsA qtr((char[]) {0, 1, 2}, 3);
 +
 +
void setup()
 +
{
 +
  // optional: wait for some input from the user, such as  a button press
 +
 +
  // then start calibration phase and move the sensors over both
 +
  // reflectance extremes they will encounter in your application:
 +
  int i;
 +
  for (i = 0; i < 250; i++)  // make the calibration take about 5 seconds
 +
  {
 +
    qtr.calibrate();
 +
    delay(20);
 +
  }
 +
 +
  // optional: signal that the calibration phase is now over and wait for further
 +
  // input from the user, such as a button press
 +
}</syntaxhighlight>
 +
 +
=== Lire les senseurs ===
 +
This library gives you a number of different ways to read the sensors.
 +
 +
# You can request raw sensor values using the '''read()''' method, which takes an optional argument that lets you perform the read with the IR emitters turned off (note that turning the emitters off is only supported by the QTR-8x reflectance sensor arrays).
 +
# You can request calibrated sensor values using the '''readCalibrated()''' method, which also takes an optional argument that lets you perform the read with the IR emitters turned off. Calibrated sensor values will always range from 0 to 1000, with 0 being as or more reflective (i.e. whiter) than the most reflective surface encountered during calibration, and 1000 being as or less reflective (i.e. blacker) than the least reflective surface encountered during calibration.
 +
# For line-detection applications, you can request the line location using the '''readLine()''' method, which takes as optional parameters a boolean that indicates whether the line is white on a black background or black on a white background, and a boolean that indicates whether the IR emitters should be on or off during the measurement. '''readLine()''' provides calibrated values for each sensor and returns an integer that tells you where it thinks the line is. If you are using N sensors, a returned value of 0 means it thinks the line is on or to the outside of sensor 0, and a returned value of 1000 * (N-1) means it thinks the line is on or to the outside of sensor N-1. As you slide your sensors across the line, the line position will change monotonically from 0 to 1000 * (N-1), or vice versa. This line-position value can be used for closed-loop PID control.
 +
 +
A sample routine to obtain the sensor values and perform rudimentary line following would be:
 +
 +
<syntaxhighlight lang="C">void loop()
 +
{
 +
  unsigned int sensors[3];
 +
  // get calibrated sensor values returned in the sensors array, along with the line position
 +
  // position will range from 0 to 2000, with 1000 corresponding to the line over the middle
 +
  // sensor.
 +
  int position = qtr.readLine(sensors);
 +
 +
  // if all three sensors see very low reflectance, take some appropriate action for this
 +
  // situation.
 +
  if (sensors[0] > 750 && sensors[1] > 750 && sensors[2] > 750)
 +
  {
 +
    // do something.  Maybe this means we're at the edge of a course or about to fall off
 +
    // a table, in which case, we might want to stop moving, back up, and turn around.
 +
    return;
 +
  }
 +
 +
  // compute our "error" from the line position.  We will make it so that the error is zero
 +
  // when the middle sensor is over the line, because this is our goal.  Error will range from
 +
  // -1000 to +1000.  If we have sensor 0 on the left and sensor 2 on the right,  a reading of
 +
  // -1000 means that we see the line on the left and a reading of +1000 means we see the
 +
  // line on the right.
 +
  int error = position - 1000;
 +
 +
  int leftMotorSpeed = 100;
 +
  int rightMotorSpeed = 100;
 +
  if (error < -500)  // the line is on the left
 +
    leftMotorSpeed = 0;  // turn left
 +
  if (error > 500)  // the line is on the right
 +
    rightMotorSpeed = 0;  // turn right
 +
 +
  // set motor speeds using the two motor speed variables above
 +
}</syntaxhighlight>
 +
 +
=== Contrôle PID ===
 +
The integer value returned by '''readLine()''' can be easily converted into a measure of your position error for line-following applications, as was demonstrated in the previous code sample. The function used to generate this position/error value is designed to be monotonic, which means the value will almost always change in the same direction as you sweep your sensors across the line. This makes it a great quantity to use for PID control.
 +
 +
Explaining the nature of PID control is beyond the scope of this document, but [http://en.wikipedia.org/wiki/PID_controller wikipedia has a very good article] (''anglais'') on the subject.
 +
 +
The following code gives a very simple example of PD control (I find the integral PID term is usually not necessary when it comes to line following). The specific nature of the constants will be determined by your particular application, but you should note that the derivative constant ''Kd'' is usually much bigger than the proportional constant ''Kp''. This is because the derivative of the error is a much smaller quantity than the error itself, so in order to produce a meaningful correction it needs to be multiplied by a much larger constant.
 +
 +
<syntaxhighlight lang="C">int lastError = 0;
 +
 +
void loop()
 +
{
 +
  unsigned int sensors[3];
 +
  // get calibrated sensor values returned in the sensors array, along with the line position
 +
  // position will range from 0 to 2000, with 1000 corresponding to the line over the middle
 +
  // sensor
 +
  int position = qtr.readLine(sensors);
 +
 +
  // compute our "error" from the line position.  We will make it so that the error is zero when
 +
  // the middle sensor is over the line, because this is our goal.  Error will range from
 +
  // -1000 to +1000.  If we have sensor 0 on the left and sensor 2 on the right,  a reading of
 +
  // -1000 means that we see the line on the left and a reading of +1000 means we see the
 +
  // line on the right.
 +
  int error = position - 1000;
 +
 +
  // set the motor speed based on proportional and derivative PID terms
 +
  // KP is the a floating-point proportional constant (maybe start with a value around 0.1)
 +
  // KD is the floating-point derivative constant (maybe start with a value around 5)
 +
  // note that when doing PID, it's very important you get your signs right, or else the
 +
  // control loop will be unstable
 +
  int motorSpeed = KP * error + KD * (error - lastError);
 +
  lastError = error;
 +
 +
  // M1 and M2 are base motor speeds.  That is to say, they are the speeds the motors should
 +
  // spin at if you are perfectly on the line with no error.  If your motors are well matched,
 +
  // M1 and M2 will be equal.  When you start testing your PID loop, it might help to start with
 +
  // small values for M1 and M2.  You can then increase the speed as you fine-tune your
 +
  // PID constants KP and KD.
 +
  int m1Speed = M1 + motorSpeed;
 +
  int m2Speed = M2 - motorSpeed;
 +
 +
  // it might help to keep the speeds positive (this is optional)
 +
  // note that you might want to add a similiar line to keep the speeds from exceeding
 +
  // any maximum allowed value
 +
  if (m1Speed < 0)
 +
    m1Speed = 0;
 +
  if (m2Speed < 0)
 +
    m2Speed = 0;
 +
 +
  // set motor speeds using the two motor speed variables above
 +
}</syntaxhighlight>
    
{{Pololu-Senseur-QTR-TRAILER}}
 
{{Pololu-Senseur-QTR-TRAILER}}
29 917

modifications

Menu de navigation