Kodlayıcılar - Yazılım

Not

This section covers encoders in software. For a hardware guide to encoders, see Kodlayıcılar-Donanım.

Kodlayıcılar hareket (genellikle bir milin rotasyon) ölçümünde kullanılan cihazlardır.

Önemli

Bu belgedeki sınıflar yalnızca roboRIO’ya doğrudan bağlanan kodlayıcılar için geçerlidir! Motor kontrolörlere bağlanan kodlayıcılar için lütfen ilgili satıcıların belgelerine danışınız.

Dördün Kodlayıcılar - Encoder Sınıfı

WPILib provides support for quadrature encoders through the Encoder class (Java, C++). This class provides a simple API for configuring and reading data from encoders.

Dördün Kodlayıcılar, bir darbenin (A veya B) darbe kanallarından ilk hangisine ulaştığını gözlemleyerek yön belirlemektedir.

Bu kodlayıcılar; iki kanal üzerinden, (adı üzerinde dördün) çeyrek aralıkla birbirleriyle örtüşmeyen kare dalga sinyalleri oluşturmaktadır. Darbeler, rotasyonun ölçümünde kullanılmakta ve ölçülen hareketin yönü hangi kanalın diğerinden “önce geldiğine” göre belirlenebilmektedir.

A, B ve indeks sinyallerini çözümleyen bir Dördün Kodlayıcı.

FPGA dördün kodlayıcıları kod çözme türüne göre ya bir sayaç modülü ya da bir kodlayıcı modülü üzerinden yönetmektedir. Bu seçim WPILib’de kendiliğinden yapılmaktadır. FPGA 8 adet kodlayıcı modülüne sahiptir.

Dördün kodlayıcı örnekleri:

Dördün Bir Kodlayıcının Başlatılması

Dördün bir kodlayıcı aşağıdaki şekilde örneklendirilebilmektedir:

  // Initializes an encoder on DIO pins 0 and 1
  // Defaults to 4X decoding and non-inverted
  Encoder m_encoder = new Encoder(0, 1);
  // Initializes an encoder on DIO pins 0 and 1
  // Defaults to 4X decoding and non-inverted
  frc::Encoder m_encoder{0, 1};

Kod Çözme Türü

WPILib Encoder sınıfı, kodlayıcı sinyallerinin kodunu üç farklı modda çözebilmektedir:

  • 1X Decoding: Increments the distance for every complete period of the encoder signal (once per four edges).

  • 2X Decoding: Increments the distance for every half-period of the encoder signal (once per two edges).

  • 4X Decoding: Increments the distance for every edge of the encoder signal (four times per period).

4X decoding offers the greatest precision, but at the potential cost of increased “jitter” in rate measurements. To use a different decoding type, use the following constructor:

  // Initializes an encoder on DIO pins 0 and 1
  // 2X encoding and non-inverted
  Encoder m_encoder2x = new Encoder(0, 1, false, Encoder.EncodingType.k2X);
  // Initializes an encoder on DIO pins 0 and 1
  // 2X encoding and non-inverted
  frc::Encoder m_encoder2x{0, 1, false, frc::Encoder::EncodingType::k2X};

Dördün Kodlayıcı Parametrelerinin Yapılandırılması

Not

The Encoder class does not make any assumptions about units of distance; it will return values in whatever units were used to calculate the distance-per-pulse value. Users thus have complete control over the distance units used. However, units of time are always in seconds.

Not

Mesafe başı darbe hesaplamasındaki darbe sayısı kod çözme türüne bağlı değildir, her bir “darbe” tam bir döngü (dört kenarlı) sayılmalıdır.

The Encoder class offers a number of configuration methods:

    // Configures the encoder to return a distance of 4 for every 256 pulses
    // Also changes the units of getRate
    m_encoder.setDistancePerPulse(4.0 / 256.0);
    // Configures the encoder to consider itself stopped after .1 seconds
    m_encoder.setMaxPeriod(0.1);
    // Configures the encoder to consider itself stopped when its rate is below 10
    m_encoder.setMinRate(10);
    // Reverses the direction of the encoder
    m_encoder.setReverseDirection(true);
    // Configures an encoder to average its period measurement over 5 samples
    // Can be between 1 and 127 samples
    m_encoder.setSamplesToAverage(5);
    // Configures the encoder to return a distance of 4 for every 256 pulses
    // Also changes the units of getRate
    m_encoder.SetDistancePerPulse(4.0 / 256.0);
    // Configures the encoder to consider itself stopped after .1 seconds
    m_encoder.SetMaxPeriod(0.1_s);
    // Configures the encoder to consider itself stopped when its rate is below
    // 10
    m_encoder.SetMinRate(10);
    // Reverses the direction of the encoder
    m_encoder.SetReverseDirection(true);
    // Configures an encoder to average its period measurement over 5 samples
    // Can be between 1 and 127 samples
    m_encoder.SetSamplesToAverage(5);

Dördün Kodlayıcılar Üzerinden Bilgi Okumak

Encoder sınıfı, kullanıcıya kodlayıcının hareketi hakkında bir sürü bilgi sağlamaktadır.

Mesafe

Not

Dördün kodlayıcılar mutlak değil, göreceli mesafeyi ölçmektedir; geri döndürülen mesafe değeri, kodlayıcının robotun başlatıldığı veya kodlayıcı değerinin en son yeniden başlatıldığı andaki konumuna bağlı olacaktır.

Users can obtain the total distance traveled by the encoder with the getDistance() method:

    // Gets the distance traveled
    m_encoder.getDistance();
    // Gets the distance traveled
    m_encoder.GetDistance();

Rate

Not

Units of time for the Encoder class are always in seconds.

Users can obtain the current rate of change of the encoder with the getRate() method:

    // Gets the current rate of the encoder
    m_encoder.getRate();
    // Gets the current rate of the encoder
    m_encoder.GetRate();

Stopped

Users can obtain whether the encoder is stationary with the getStopped() method:

    // Gets whether the encoder is stopped
    m_encoder.getStopped();
    // Gets whether the encoder is stopped
    m_encoder.GetStopped();

Direction

Users can obtain the direction in which the encoder last moved with the getDirection() method:

    // Gets the last direction in which the encoder moved
    m_encoder.getDirection();
    // Gets the last direction in which the encoder moved
    m_encoder.GetDirection();

Period

Users can obtain the period of the encoder pulses (in seconds) with the getPeriod() method:

    // Gets the current period of the encoder
    m_encoder.getPeriod();
    // Gets the current period of the encoder
    m_encoder.GetPeriod();

Dördün Bir Kodlayıcının Yeniden Başlatılması

Dördün kodlayıcıyı mesafe okuması sıfır olacak bir şekilde yeniden başlatmak istiyorsanız, reset() metodunu çağırınız. Yeniden başlatma ölçülen mesafenin istenen fiziksel mesafe ile örtüşmesini sağlamak için faydalı ve genellikle özgüdümleme rutininde çağrılmaktadır:

    // Resets the encoder to read a distance of zero
    m_encoder.reset();
    // Resets the encoder to read a distance of zero
    m_encoder.Reset();

Duty Cycle Encoders - The DutyCycleEncoder class

WPILib provides support for duty cycle (also marketed as PWM) encoders through the DutyCycleEncoder class (Java, C++). This class provides a simple API for configuring and reading data from duty cycle encoders.

roboRIO’nın FPGA’sı görev döngüsü kodlayıcılarını kendiliğinden yönetmektedir.

Uyarı

In 2025 the API changed to remove rollover detection as rollover detection did not work. The get() method returns the value within a rotation where the maximum value in a rotation is defined in the constructor (default 1).

Görev döngüsü kodlayıcıları örnekleri:

Bir Görev Döngüsü Kodlayıcısının Başlatılması

A duty cycle encoder can be instantiated as follows:

  // Initializes a duty cycle encoder on DIO pins 0
  DutyCycleEncoder m_encoder = new DutyCycleEncoder(0);
  // Initializes a duty cycle encoder on DIO pins 0
  frc::DutyCycleEncoder m_encoder{0};

Configuring Duty Cycle Encoder Range and Zero

Not

The DutyCycleEncoder class does not assume specific units of rotation. It returns values in the same units used to calculate the full range of rotation, giving users complete control over the rotation units.

DutyCycleEncoder sınıfı, kullanıcılara kodlayıcının tam hareket alanı ve sıfır konumu üzerinde eksiksiz kontrol olanağı tanıyan başka constructor seçenekleri sağlamaktadır.

Sıfır konumu ölçülen rotasyonun istenen fiziksel rotasyonla örtüştüğünden emin olmak adına faydalıdır. Dördün kodlayıcıların aksine görev döngüsü kodlayıcılarının özgüdümlenmesi şart değildir. İstenilen rotasyon, program başlatıldığı zaman okunup depolanacak şekilde ayarlanabilmektedir. Tercihler sınıfı bu değerleri roboRIO’ya kaydetmek ve değerlere roboRIO’dan erişmek için metodlar sağlamaktadır.

  // Initializes a duty cycle encoder on DIO pins 0 to return a value of 4 for
  // a full rotation, with the encoder reporting 0 half way through rotation (2
  // out of 4)
  DutyCycleEncoder m_encoderFR = new DutyCycleEncoder(0, 4.0, 2.0);
  // Initializes a duty cycle encoder on DIO pins 0 to return a value of 4 for
  // a full rotation, with the encoder reporting 0 half way through rotation (2
  // out of 4)
  frc::DutyCycleEncoder m_encoderFR{0, 4.0, 2.0};

Görev Döngüsü Kodlayıcıları Üzerinden Rotasyonun Okunması

Not

Görev Döngüsü kodlayıcıları mutlak rotasyon ölçümü yaptıkları için ölçüm kodlayıcının başlangıç konumuna bağlı değildir.

Kullanıcılar, kodlayıcı tarafından ölçülmüş rotasyona get() metodu ile erişebilmektedir:

    // Gets the rotation
    m_encoder.get();
    // Gets the rotation
    m_encoder.Get();

Görev Döngüsü Kodlayıcısının Bağlandığını Tespit Etmek

Görev döngüsü kodlayıcıları sürekli bir darbe dizisi ürettikleri için kodlayıcının bağlanıp bağlanmadığını belirlemek mümkündür.

    // Gets if the encoder is connected
    m_encoder.isConnected();
    // Gets if the encoder is connected
    m_encoder.IsConnected();

Analog Kodlayıcılar - AnalogEncoder Sınıfı

WPILib provides support for analog absolute encoders through the AnalogEncoder class (Java, C++). This class provides a simple API for configuring and reading data from analog encoders.

Analog kodlayıcı örnekleri:

Analog Bir Kodlayıcının Başlatılması

Analog bir kodlayıcı aşağıdaki şekilde örneklendirilebilmektedir:

  // Initializes an analog encoder on Analog Input pin 0
  AnalogEncoder m_encoder = new AnalogEncoder(0);
  // Initializes an analog encoder on Analog Input pin 0
  frc::AnalogEncoder m_encoder{0};

Analog Kodlayıcının Etki Alanı ve Sıfırının Yapılandırılması

Not

AnalogEncoder sınıfı, belirli rotasyon birimleri varsaymamaktadır. Sınıf değerleri bütün bir rotasyon açıklığının hesaplanmasında kullanılan birimlerin aynılarıyla döndürerek kullanıcılara rotasyon birimleri üzerinde eksiksiz bir kontrol olanağı tanımaktadır.

AnalogEncoder sınıfı, kullanıcılara kodlayıcının tam hareket alanı ve sıfır konumu üzerinde eksiksiz kontrol olanağı tanıyan başka constructor seçenekleri sağlamaktadır.

Sıfır konumu ölçülen rotasyonun istenen fiziksel rotasyonla örtüştüğünden emin olmak adına faydalıdır. Dördün kodlayıcıların aksine analog kodlayıcıların özgüdümlenmesi şart değildir. İstenilen rotasyon, program başlatıldığı zaman okunup depolanacak şekilde ayarlanabilmektedir. Tercihler sınıfı bu değerleri roboRIO’ya kaydetmek ve değerlere roboRIO’dan erişmek için metodlar sağlamaktadır.

  // Initializes an analog encoder on DIO pins 0 to return a value of 4 for
  // a full rotation, with the encoder reporting 0 half way through rotation (2
  // out of 4)
  AnalogEncoder m_encoderFR = new AnalogEncoder(0, 4.0, 2.0);
  // Initializes an analog encoder on DIO pins 0 to return a value of 4 for
  // a full rotation, with the encoder reporting 0 half way through rotation (2
  // out of 4)
  frc::AnalogEncoder m_encoderFR{0, 4.0, 2.0};

Analog Kodlayıcılar Üzerinden Rotasyonun Okunması

Not

Analog kodlayıcılar mutlak rotasyon ölçümü yaptıkları için ölçüm kodlayıcının başlangıç konumuna bağlı değildir.

Kullanıcılar, kodlayıcı tarafından ölçülmüş rotasyona get() metodu ile erişebilmektedir:

    // Gets the rotation
    m_encoder.get();
    // Gets the rotation
    m_encoder.Get();

Kodlayıcıların Kod içerisinde Kullanımı

Encoders are some of the most useful sensors in FRC®; they are very nearly a requirement to make a robot capable of nontrivially-automated actuations and movement. The potential applications of encoders in robot code are too numerous to summarize fully here, but an example is provided below:

Driving to a Distance

Encoders can be used on a robot drive to create a simple “drive to distance” routine. This is useful in autonomous mode, but has the disadvantage that the robot’s momentum will cause it to overshoot the intended distance. Better methods include using a PID Controller or using Path Planning

Not

The following example uses the Encoder class, but is similar if other DutyCycleEncoder or AnalogEncoder is used. However, quadrature encoders are typically better suited for drivetrains since they roll over many times and don’t have an absolute position.

  // Creates an encoder on DIO ports 0 and 1
  Encoder m_encoder = new Encoder(0, 1);
  // Initialize motor controllers and drive
  Spark m_leftLeader = new Spark(0);
  Spark m_leftFollower = new Spark(1);
  Spark m_rightLeader = new Spark(2);
  Spark m_rightFollower = new Spark(3);
  DifferentialDrive m_drive = new DifferentialDrive(m_leftLeader::set, m_rightLeader::set);

  /** Called once at the beginning of the robot program. */
  public Robot() {
    // Configures the encoder's distance-per-pulse
    // The robot moves forward 1 foot per encoder rotation
    // There are 256 pulses per encoder rotation
    m_encoder.setDistancePerPulse(1.0 / 256.0);
    // Invert the right side of the drivetrain. You might have to invert the other side
    m_rightLeader.setInverted(true);
    // Configure the followers to follow the leaders
    m_leftLeader.addFollower(m_leftFollower);
    m_rightLeader.addFollower(m_rightFollower);
  }

  /** Drives forward at half speed until the robot has moved 5 feet, then stops. */
  @Override
  public void autonomousPeriodic() {
    if (m_encoder.getDistance() < 5.0) {
      m_drive.tankDrive(0.5, 0.5);
    } else {
      m_drive.tankDrive(0.0, 0.0);
    }
  }
  // Creates an encoder on DIO ports 0 and 1.
  frc::Encoder m_encoder{0, 1};
  // Initialize motor controllers and drive
  frc::Spark leftLeader{0};
  frc::Spark leftFollower{1};
  frc::Spark rightLeader{2};
  frc::Spark rightFollower{3};
  frc::DifferentialDrive drive{[&](double output) { leftLeader.Set(output); },
                               [&](double output) { rightLeader.Set(output); }};
  Robot() {
    // Configures the encoder's distance-per-pulse
    // The robot moves forward 1 foot per encoder rotation
    // There are 256 pulses per encoder rotation
    m_encoder.SetDistancePerPulse(1.0 / 256.0);
    // Invert the right side of the drivetrain. You might have to invert the
    // other side
    rightLeader.SetInverted(true);
    // Configure the followers to follow the leaders
    leftLeader.AddFollower(leftFollower);
    rightLeader.AddFollower(rightFollower);
  }
  void AutonomousPeriodic() override {
    // Drives forward at half speed until the robot has moved 5 feet, then
    // stops:
    if (m_encoder.GetDistance() < 5) {
      drive.TankDrive(0.5, 0.5);
    } else {
      drive.TankDrive(0, 0);
    }
  }

Homing a Mechanism

Since quadrature encoders measure relative distance, it is often important to ensure that their “zero-point” is in the right place. A typical way to do this is a “homing routine,” in which a mechanism is moved until it hits a known position (usually accomplished with a limit switch), or “home,” and then the encoder is reset. The following code provides a basic example:

Not

Homing is not necessary for absolute encoders like duty cycle encoders and analog encoders.

  Encoder m_encoder = new Encoder(0, 1);
  Spark m_spark = new Spark(0);
  // Limit switch on DIO 2
  DigitalInput m_limit = new DigitalInput(2);

  /**
   * Runs the motor backwards at half speed until the limit switch is pressed then turn off the
   * motor and reset the encoder.
   */
  @Override
  public void autonomousPeriodic() {
    if (!m_limit.get()) {
      m_spark.set(-0.5);
    } else {
      m_spark.set(0.0);
      m_encoder.reset();
    }
  }
  frc::Encoder m_encoder{0, 1};
  frc::Spark m_spark{0};
  // Limit switch on DIO 2
  frc::DigitalInput m_limit{2};
  void AutonomousPeriodic() override {
    // Runs the motor backwards at half speed until the limit switch is pressed
    // then turn off the motor and reset the encoder
    if (!m_limit.Get()) {
      m_spark.Set(-0.5);
    } else {
      m_spark.Set(0);
      m_encoder.Reset();
    }
  }