Skip to content

Commit

Permalink
Merge pull request #5 from DeepBlueRobotics/fix-pwm-port-numbers
Browse files Browse the repository at this point in the history
Update fake PWM ports to increment their values by 10
  • Loading branch information
CoolSpy3 authored Dec 27, 2020
2 parents 5c0cfe2 + 80c7199 commit fad1cc5
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 26 deletions.
29 changes: 16 additions & 13 deletions src/main/java/frc/robot/lib/sim/MockSparkMax.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,26 @@
import com.revrobotics.CANError;
import com.revrobotics.CANSparkMax;

import edu.wpi.first.wpilibj.Spark;
import edu.wpi.first.hal.SimDevice;
import edu.wpi.first.hal.SimDouble;
import frc.robot.lib.Mocks;

public class MockSparkMax extends CANSparkMax {
// Assign the CAN port to a PWM port so it works with the simulator. Not a fan of this solution though
// CAN ports should be separate from PWM ports
private final int portPWM;
private final Spark motorPWM;
private final int port;
private final SimDevice motor;
private final SimDouble speed;
private CANEncoder encoder;
private boolean isInverted;
// Since we need to keep a record of all the motor's followers
private static HashMap<Integer, Spark> followMap = new HashMap<Integer, Spark>();
private static HashMap<Integer, SimDouble> followMap = new HashMap<>();

public MockSparkMax(int portPWM, MotorType type) {
super(portPWM, type);
this.portPWM = portPWM;
motorPWM = new Spark(portPWM);
public MockSparkMax(int port, MotorType type) {
super(port, type);
this.port = port;
motor = SimDevice.create("SparkMax", port);
speed = motor.createDouble("Motor Output", false, 0);
encoder = Mocks.createMock(CANEncoder.class, new MockedSparkEncoder(this));
isInverted = false;
}
Expand All @@ -34,24 +37,24 @@ public static CANSparkMax createMockSparkMax(int portPWM, MotorType type) {
@Override
public void set(double speed) {
speed = (isInverted ? -1.0 : 1.0) * speed;
motorPWM.set(speed);
if (followMap.containsKey(portPWM)) followMap.get(portPWM).set(speed);
this.speed.set(speed);
if (followMap.containsKey(port)) followMap.get(port).set(speed);
}

@Override
public CANError follow(CANSparkMax leader) {
if (!followMap.containsValue(motorPWM)) followMap.put(leader.getDeviceId(), motorPWM);
if (!followMap.containsValue(speed)) followMap.put(leader.getDeviceId(), speed);
return CANError.kOk;
}

@Override
public double get() {
return motorPWM.get();
return speed.get();
}

@Override
public int getDeviceId() {
return portPWM;
return port;
}

@Override
Expand Down
25 changes: 12 additions & 13 deletions src/main/java/frc/robot/lib/sim/MockedSparkEncoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,49 +4,48 @@
import com.revrobotics.CANError;
import com.revrobotics.CANSparkMax;

import edu.wpi.first.wpilibj.Encoder;
import edu.wpi.first.wpilibj.simulation.EncoderSim;
import edu.wpi.first.hal.SimDevice;
import edu.wpi.first.hal.SimDouble;

public class MockedSparkEncoder extends CANEncoder {
private Encoder encoder;
private EncoderSim encoderSim;
private SimDevice device;
private SimDouble dpp;
private SimDouble count;
// Default value for a CANEncoder
private final int countsPerRevolution = 4096;
// Used for linking EncoderSim with Encoder
private static int encodersCreated = 0;

public MockedSparkEncoder(CANSparkMax motor) {
super(motor);
int id = motor.getDeviceId();
// Match motor on CAN 0 with channels [0, 1], CAN 1 to channels [2, 3], etc.
// Probably not the best way to do it but it works
encoder = new Encoder(2 * id, 2 * id + 1);
encoderSim = EncoderSim.createForIndex(encodersCreated);
encodersCreated++;
device = SimDevice.create("CANEncoder_SparkMax", id);
dpp = device.createDouble("distancePerPulse", false, 1);
count = device.createDouble("count", false, 0);
}

@Override
public double getPosition() {
return encoder.getDistance();
return dpp.get() * count.get();
}

@Override
public CANError setPositionConversionFactor(double positionConversionFactor) {
// Assume positionConversionFactor = units/rev
// distancePerPulse (actually distance per count) = units/rev * rev/count
encoder.setDistancePerPulse(positionConversionFactor / countsPerRevolution);
dpp.set(positionConversionFactor / countsPerRevolution);
return CANError.kOk;
}

@Override
public CANError setPosition(double position) {
double revolutions = position / getPositionConversionFactor();
encoderSim.setCount((int) Math.floor(revolutions * countsPerRevolution));
count.set((int) Math.floor(revolutions * countsPerRevolution));
return CANError.kOk;
}

@Override
public double getPositionConversionFactor() {
return encoder.getDistancePerPulse() * countsPerRevolution;
return dpp.get() * countsPerRevolution;
}
}

0 comments on commit fad1cc5

Please sign in to comment.