Paso 3: Actualización del modelo de transmisión

Ahora que se ha hecho el modelo de transmisión, necesita ser actualizado periódicamente con los últimos comandos de voltaje del motor. Se recomienda hacer este paso en un método separado simulationPeriodic() / SimulationPeriodic() dentro de su subsistema y sólo llamar a este método en la simulación.

Nota

Si está utilizando el marco basado en comandos, cada subsistema que extiende SubsystemBase tiene un simulationPeriodic() / SimulationPeriodic() que puede ser anulado. Este método se ejecuta automáticamente sólo durante la simulación. Si no está utilizando la biblioteca basada en comandos, asegúrese de llamar a su método de simulación dentro de la clase simulationPeriodic() / SimulationPeriodic() de la clase principal Robot. Estos métodos periódicos también son llamados automáticamente sólo durante la simulación.

Hay tres pasos principales para actualizar el modelo:

  1. Establezca el entrada del modelo de transmisión. Estos son los voltajes del motor de los dos lados del tren de transmisión.

  2. Haga avanzar el modelo en el tiempo por el paso de tiempo periódico nominal (generalmente 20 ms). Esto actualiza todos los estados de la transmisión (es decir, pose, posiciones del codificador y velocidades) como si hubieran pasado los 20 ms.

  3. Actualice los sensores simulados con nuevas posiciones, velocidades y ángulos para usar en otros lugares.

private PWMSparkMax m_leftMotor = new PWMSparkMax(0);
private PWMSparkMax m_rightMotor = new PWMSparkMax(1);

public Drivetrain() {
  ...
  m_leftEncoder.setDistancePerPulse(2 * Math.PI * kWheelRadius / kEncoderResolution);
  m_rightEncoder.setDistancePerPulse(2 * Math.PI * kWheelRadius / kEncoderResolution);
}

public void simulationPeriodic() {
  // Set the inputs to the system. Note that we need to convert
  // the [-1, 1] PWM signal to voltage by multiplying it by the
  // robot controller voltage.
  m_driveSim.setInputs(m_leftMotor.get() * RobotController.getInputVoltage(),
                       m_rightMotor.get() * RobotController.getInputVoltage());

  // Advance the model by 20 ms. Note that if you are running this
  // subsystem in a separate thread or have changed the nominal timestep
  // of TimedRobot, this value needs to match it.
  m_driveSim.update(0.02);

  // Update all of our sensors.
  m_leftEncoderSim.setDistance(m_driveSim.getLeftPositionMeters());
  m_leftEncoderSim.setRate(m_driveSim.getLeftVelocityMetersPerSecond());
  m_rightEncoderSim.setDistance(m_driveSim.getRightPositionMeters());
  m_rightEncoderSim.setRate(m_driveSim.getRightVelocityMetersPerSecond());
  m_gyroSim.setAngle(-m_driveSim.getHeading().getDegrees());
}

Importante

Si el lado derecho de su transmisión está invertido, DEBE negar el voltaje correcto en la llamada SetInputs() para asegurarse de que los voltajes positivos corresponden al movimiento hacia adelante.

Importante

Debido a que el modelo del simulador de tren de conducción devuelve las posiciones y las velocidades en metros y m/s respectivamente, éstas deben ser convertidas en ticks de codificación y ticks/s cuando se llama a SetDistance() y SetRate(). Alternativamente, puedes configurar SetDistancePerPulse en los codificadores para que el objeto Encoder se encargue de esto automáticamente - este es el enfoque que se toma en el ejemplo anterior.

Ahora que las posiciones simuladas del codificador, las velocidades y los ángulos del giroscopio se han establecido, puedes llamar a m_leftEncoder.GetDistance(), etc. en tu código de robot como normalmente y se comportará exactamente como lo haría en un robot real. Esto implica realizar cálculos de odometría, ejecutar bucles de retroalimentación PID de velocidad para el seguimiento de la trayectoria, etc.