Swerve path is far off from intended start position

We are a new team - joining FRC with Crescendo - that was recently able to build a swerve drivetrain utilizing NEO motors in SDS MK4i modules. I am the lead programmer for our team, and I have been having trouble properly implementing an autonomous using the Pathplanner libraries and GUI app.

I am using the PracticalNeoSwerve template from Team 364, paired with the basic code from the “Getting started” from the Pathplanner Lib page.

I was able to get the robot to drive with teleop fine, but my issue stems from the autonomous path having the starting position be way off than what was intended when making the path. I tried toggling “Preset Starting Pose” on and off and dragging the robot to where I want the path to start, to no avail. The telemetry in the pathplanner app suggests a position so far off the field, it won’t be displayed until ~10 seconds later, when the robot eventually returns to its position.

I’m positive I missed some sort of modifications I need to do to the code to fix these issues, but I’m still very inexperienced in programming such a drivetrain that I’m stumped on what the issue might be. My best guess is that the odometry is messing up somewhere, such that the robot doesn’t know where it is at the start.

I come as the programmer from my VEX team, and I fully understand PID (to the extent that VEX typically uses), and I have a basic grasp of odometry, if that information helps.

Below is a GIF of my laptop showing the auton running with the robot propped up on two chairs.

Any help would be greatly appreciated!
ezgif-6-38462d04ac

1 Like

Hello, welcome to CD! :grinning:

That’s a reasonable guess, so how about we start looking at that?

You’ll notice a getPose() method in your swerve subsystem, which returns the estimated pose by your odometry. You can send this data to your dashboard using the Field2d object.

You would also need to bind a button on your controller to reset the odometry.

// In RobotContainer.java
private void configureKeyBindings() {
  ... // other command bindings
  // configure button "A" to reset your odometry
  controller.a().onTrue(Commands.runOnce(() -> drive.resetOdometry(new Pose(3, 3, Rotation2d.fromDegrees(0))), drive))
}

Now, you can enable your robot in teleOp, try resetting the odometry, and drive it around to see if it works properly.

Also, look into how you configured PathPlanner. Your code should include an AutoBuilder.configure() statement. It would be best to share that code or the link to your project.

I was able to add the controller binding to reset the odometry, but it didn’t seem to do anything. I also added it to the beginning of the getAutonomousCommand command in robotContainer to see if that did anything, but no changes either.

I sent the field data to smartDashboard - but I was able to do it today, meaning that I wasn’t able to verify if it correct displays to smartDashboard since I couldn’t try it at school.

I also just realized the documentation for Pathplanner updated to its 2025 iteration, so I tried to update my project and rewrite the AutoBuilder.configure() method within my Swerve subsystem.

Here is the link to my GitHub project: https://github.com/ammmarHussain/FRC9779

Some silly mechanical questions, just in case something here may be making a different issue harder to diagnose:

What surface are you driving on (field carpet, carpet squares, sealed concrete, only up on blocks, etc)?

What wheel type (rough top, colson, etc)?

Are all the gear ratios you have in the code correct? What gear ratio are you using?

As it stands right now, the robot is propped up for the autonomous - we don’t have a sufficient driving area such that the robot can safely stop without hitting the walls. We usually drive on hard tiles and tested the autonomous a bit on that.

Testing it on the floor didn’t seem to stop the original issue of the wrong starting position, so I figured propping it up would be fine.

We’re using colson wheels, but you’re right - the default gear ratios in the program were L2 and we got the L3 gear ratios. I changed it now - thanks for reminding me!! rookie mistake huh

1 Like

Propping it up efficiently takes accerating the robot mass out of the equation, so it will not be a 1:1 comparison. If you are relying on on the gyro to see a turn and it doesn’t (because it is propped up), that is an issue too.

(Colsons will also perform different on carpet; if you are confused by why you can’t return to the same location on carpet that is why. Give it a search on CD when/if it comes up, there a few threads on the matter)

2 Likes

You might want to add .ignoringDisable(true) to that command to ensure it will work without having to enable the robot.

1 Like

We made faster progress when we fell back to creating a 1 second delay, 0.3 meter (1 foot), 0.1 m/s auto.

That was our “hello world” auto and then we built up from there, learning what the preset checkbox does, learning how to marry up the simulation world and the real robot world (so you can do most of the later path/auto development in the sim)

One Foot Slow Path.path
{
  "version": 1.0,
  "waypoints": [
    {
      "anchor": {
        "x": 0.0,
        "y": 0.0
      },
      "prevControl": null,
      "nextControl": {
        "x": 0.25,
        "y": 0.0
      },
      "isLocked": false,
      "linkedName": null
    },
    {
      "anchor": {
        "x": 0.3,
        "y": 0.0
      },
      "prevControl": {
        "x": 0.04999999999999999,
        "y": 0.0
      },
      "nextControl": null,
      "isLocked": false,
      "linkedName": null
    }
  ],
  "rotationTargets": [],
  "constraintZones": [],
  "eventMarkers": [],
  "globalConstraints": {
    "maxVelocity": 0.1,
    "maxAcceleration": 3.0,
    "maxAngularVelocity": 540.0,
    "maxAngularAcceleration": 720.0
  },
  "goalEndState": {
    "velocity": 0,
    "rotation": 0,
    "rotateFast": false
  },
  "reversed": false,
  "folder": null,
  "previewStartingState": {
    "rotation": 0,
    "velocity": 0
  },
  "useDefaultConstraints": false
}
One Foot Slow Auto.auto

{
“version”: 1.0,
“startingPose”: {
“position”: {
“x”: 0.0,
“y”: 0.0
},
“rotation”: 0
},
“command”: {
“type”: “sequential”,
“data”: {
“commands”: [
{
“type”: “wait”,
“data”: {
“waitTime”: 1.0
}
},
{
“type”: “path”,
“data”: {
“pathName”: “One Foot Slow Path”
}
}
]
}
},
“folder”: null,
“choreoAuto”: false
}