wpilibsuite / frc-docs

Official FRC Documentation powered by Read the Docs
https://docs.wpilib.org
Other
148 stars 261 forks source link

Add documentation for scheduling #912

Closed Daltz333 closed 3 years ago

Daltz333 commented 3 years ago

Most of the example work is already done, see

Scheduling Functions
^^^^^^^^^^^^^^^^^^^^

- Added support for scheduling functions more often than the robot loop via ``addPeriodic()`` in TimedRobot. Previously, teams had to make a Notifier to run feedback controllers more often than the TimedRobot loop period of 20ms (running TimedRobot more often than this is not advised). Now, users can run feedback controllers more often than the main robot loop, but synchronously with the TimedRobot periodic functions so there aren't any thread safety issues.

.. tabs::

    .. group-tab:: Java

        .. code-block:: java

            public class Robot {
                private Joystick m_joystick = new Joystick(0);
                private Encoder m_encoder = new Encoder(1, 2);
                private Spark m_motor = new Spark(1);
                private PIDController m_controller = new PIDController(1.0, 0.0, 0.5, 0.01);

                public Robot() {
                    addPeriodic(() -> {
                        m_motor.set(m_controller.calculate(m_encoder.getRate()));
                    }, 0.01, 0.01);
                }

                @Override
                public teleopPeriodic() {
                    if (m_joystick.getRawButtonPressed(1)) {
                        if (m_controller.getSetpoint() == 0.0) {
                            m_controller.setSetpoint(30.0);
                        } else {
                            m_controller.setSetpoint(0.0);
                        }
                    }
                }

    .. group-tab:: C++ (Header)

        .. code-block:: cpp

            class Robot {
                private:
                    frc::Joystick m_joystick{0};
                    frc::Encoder m_encoder{1, 2};
                    frc::Spark m_motor{1};
                    frc2::PIDController m_controller{1.0, 0.0, 0.5, 10_ms};

                    Robot();

                    void TeleopPeriodic() override;

    .. group-tab:: C++ (Source)

        .. code-block:: cpp

            void Robot::Robot() {
                AddPeriodic([&] {
                    m_motor.Set(m_controller.Calculate(m_encoder.GetRate()));
                }, 10_ms, 10_ms);
            }

            void Robot::TeleopPeriodic() {
                if (m_joystick.GetRawButtonPressed(1)) {
                    if (m_controller.GetSetpoint() == 0.0) {
                        m_controller.SetSetpoint(30.0);
                    } else {
                        m_controller.SetSetpoint(0.0);
                    }
                }
            }

teleopPeriodic() in this example runs every 20ms, and the controller update is run every 10ms with an offset of 10ms from when TeleopPeriodic() runs so that their timeslots don't conflict.

Just need someone to turn this into an article and place it into some appropriate section. I think making a "Convenience Features" section under "Advanced Programming" would be great for this and some other miscellaneous articles.

Starlight220 commented 3 years ago

Shouldn't addPeriodic() calls be in robotInit() and not the constructor? And how would they access subsystem objects (that are encapsulated in RobotContainer)?

Daltz333 commented 3 years ago

I'm not sure. I just copied @calcmogul example.

calcmogul commented 3 years ago

Shouldn't addPeriodic() calls be in robotInit() and not the constructor?

Either one works. I prefer using the constructor for its intended purpose.

calcmogul commented 3 years ago

If you're using command-based, you don't need addPeriodic() because CommandScheduler is doing the scheduling instead of TimedRobot's Notifier. You'll need the scheduler Run() function to run at the rate of your fastest command (like a feedback controller).