Any reason joystick control shouldn't work for PWMClimbers subsystem in this code?

Rookie lead mentor here. NOT a programmer. (You could say our team has zero programmers).
Our Kitbot is up & running, but we’re trying to add an extra system: A pair of AndyMark climbers with motors run by Spark controllers (the original, not Spark Max). They can behave like Tank Drive - independent control from the Y values of two sticks.

I came up with this code which shows no problems – but doesn’t turn on any motors.

It’s all the example Kitbot code with the addition of the PWMClimbers subsystem and lines 78-83 in RobotContainer to give them tank drive control with the sticks of the Operator controller.

We verified the motor works and electrical connections are good, Spark is powered and has signal cable plugged in correctly.
Any other non-code items that should be checked, or is it a coding issue?

PS - Loving CD! Have already learned a ton from all the experienced contributors here. Thanks in advance for any pointers!

I didn’t see any problems, I’ll try to run it in the simulation tomorrow. I would confirm that the motor controllers are plugged in to PWM ports 1 and 2, and that they’re plugged in the right direction.

What does the LED do on the SPARK when it should be driving?

It should work, but there’s no need for the DifferentialDrive class. You can just set the duty cycle on each motor directly.

In your code, the right motor is controlled by the X axis of the right stick.

1 Like

If you wanted to simplify it a bit, you can have one motor be the leader, and one be the follower. The Spark controller allows you to set a follower to a given motor, such that when one motor runs the other should as well. (I’ve never actually used a Spark, but I believe that’s what should happen)

Your code could then look like:

public class PWMClimbers extends SubsystemBase {
  /*Class member variables. These variables represent things the class needs to keep track of and use between
  different method calls. */
  Spark m_leader = new Spark(RClimberID);
  Spark m_follower = new Spark(LClimberID);
  

  /*Constructor. This method is called when an instance of the class is created. This should generally be used to set up
   * member variables and perform any configuration or set up necessary on hardware.
   */
  public PWMClimbers() {
    // Set the follower 
    m_leader.addFollower(m_follower);  
  }

  //Method to control the climbers using tank drive.
  public void driveClimber(double speed) {
    m_leader.set(speed);
  }
}

Then your command binding would be:

// Set the default command for the climbers to operate using the Operator joysticks
    m_Climbers.setDefaultCommand(
        new RunCommand(
            () ->
                m_Climbers.driveClimber(-m_operatorController.getLeftY(), m_Climbers)
        );

In that case, you’d only need the left thumbstick’s Y axis value to drive the climber. Either up or down, depending on the direction of travel on the joystick.

Major caveat here is that both motors need to be in phase, meaning, positive voltage applied to both motors will mean they travel the same direction. Depending on how they are mounted to the mechanisms, sometimes you want to invert one side or the other in software to make them equal.

Thanks to both respondents. We fixed the incorrect axis for right motor (was a mistake of copying from arcade drive code).

Ultimately it turned out to be (probably) a bad PWM cable connection. The original code is now working as intended, and connections have been made secure with lots of zip ties & electrical tape! :slight_smile: