Send Encoder Value to SmartDashboard with profiledPIDsubsystem, New Command based ArmBot example

Hi CD -

I’m working through going from “Robot” to “Robot with Encoders” to “profiled Robot using Encoders”, using the new command framework and a Johnson Electric PLG set up with a linear actuator. The encoder feeds back into the RIO directly, and I am using a Spark Mini to control it over PWM.

When I was at “Robot with Encoders”, I had my subsystem set up to report the encoder value to SmartDashboard in the periodic() method of that subsystem.

public void periodic(){
  putNumber("EncoderX", m_encoder.getDistance());

Now that I move that subsystem over to ProfiledPIDSubsystem, the periodic() appears to have gone away, and even if I leave that periodic() in place I’m not getting encoder values on the dashboard.

Looking at the ArmBot example, where is a good place to make the robot report the encoder state to SmartDashboard?

I have tried setting the default command for the ProfiledPIDsubsystem in robotContainer to push the state to smartDashboard: I renamed periodic() to putMeasurement() and then tried to call it as either a new RunCommand or new InstantCommand. This crashed the program. What am I missing?

I don’t have code up in front of me, so take this with a grain of salt, but a ProfiledPIDSubsysten should still be a Sybsystem via inheritance, and therefore should still have a periodic method you could use.

Are you commenting that the example doesn’t show it, or that your editor doesn’t indicate that it exists?

1 Like

I added the following code to the ArmBot ArmSubsystem and ran in simulation and got updated encoder values in smart dashboard.

  public void periodic() {
    SmartDashboard.putNumber("Encoder", m_encoder.getDistance());

If you leave out the call to super.periodic(), the motor won’t ever move, because ProfiledPIDSubsystem updates the motor in periodic().

If you just want to see the encoder value, you can use the LiveWindow tab on shuffleboard, which is automatically updated, without needing to add any code.

1 Like

Thanks Joe! That makes sense, the missing super.periodic() is the key.

What’s a good way to get in and view the class, so I could catch something like this more easily?
I was clicking through the VSCode popups and found a link all the back to view the Command class that’s linked in the description of profiledPIDsubsystem, but couldn’t figure out how to view just the ProfiledPIDsubsystem class on its own, from VSCode…

Hi Joe -

The code works to display encoder values in my real project, but I couldn’t get the PIDcontroller to activate and run in my project. When I went back and ran ArmBot in Simulation, I couldn’t get the PIDcontroller to activate in the simulation either – I expected it to use the PWM4 output that’s assigned to the arm motor?

I have an xbox 360 controller connected to my PC. I started a new project from the ArmBot example, started the Simulation GUI, assigned the xbox controller to the correct joystick, and clicked “Enable” in Simulation.
I’m getting outputs on the drivebase, but clicking A & B does nothing. PWM4 doesn’t budge.

Am I missing a step? I reread the two pages in but didn’t catch anything there I haven’t done… I assigned the joystick, but do I also need to assign a sensor somehow? I can’t click & drag anything in the gui.

I think @Oblarg might have written the example since it’s in the ‘new style’ - cc’ing for visibility…

The current release of simulation doesn’t have physics built in. So, in my test, I hit the + button to increment the encoder. That’s not really feasible for testing a profiledPIDController that needs to have encoder values synced to time steps, for what you’re trying to do.

1 Like

Got it, that makes sense.

I think I can still test whether the button presses are working, and they appear to not be?

The default controller has Feedforward & Proportional only, so if the button press was successfully triggering setGoal, I would expect the PWM output to go to a steady state based on the constant error. I’m getting zeroes instead.

It appears that the ArmBot example never enables the ArmSubystem, so it never runs the PID.

OK, that makes sense, and matches the behavior I’m getting in both the example code & the project I’m trying to create with that sample code

I have no idea how to enable the Subsystem, or how the behavior should be different from the Drive, which appears to work?
Is there a code example that does enable a Subsystem?

There’s now a PR open for this… [wpilib] Enable ArmSubsystem in ArmBot example by prateekma · Pull Request #2752 · wpilibsuite/allwpilib · GitHub

TLDR: you need to call m_robotArm.enable();