Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use StandardTrackingWheelLocalizer? #25

Closed
EddieDL opened this issue Oct 20, 2019 · 27 comments
Closed

How to use StandardTrackingWheelLocalizer? #25

EddieDL opened this issue Oct 20, 2019 · 27 comments

Comments

@EddieDL
Copy link

EddieDL commented Oct 20, 2019

It isn't 100% clear how to use the StandardTrackingWheelLocalizer. I have read issue #24 and I have gone through the examples and the documentation. However, I am still not sure on a few things.

  • Is it feasible to use dead tracking wheels AND encoders on your DC motors? This seems like it would require 7 DC motor ports on REV Expansion Hubs.
  • Assuming it isn't feasible to have both dead tracking wheels AND encoders on your DC motors, what parts of the quickstart code should be removed/changed? For example, getWheelPositions, DriveConstants.TICKS_PER_REV, DriveConstants.WHEEL_RADIUS, etc.

Also, in my situation we are not able to install our lateral odometery wheels inline. In our case they are offset from the center line of the robot. What measurements should I use to utilize this configuration?

Thank you for any help you can provide.

@rbrott
Copy link
Member

rbrott commented Oct 20, 2019

Is it feasible to use dead tracking wheels AND encoders on your DC motors? This seems like it would require 7 DC motor ports on REV Expansion Hubs.

Yes, seven quadrature encoder ports are required for the seven quadrature encoders required by three tracking wheels and 4WD with feedback. You can still use three of those motor ports for other mechanisms, but you will have to use current monitoring, I2C encoders, or another sensor for feedback. This is entirely possible with road runner; however, whether it is feasible for your team depends on the design of your robot.

Assuming it isn't feasible to have both dead tracking wheels AND encoders on your DC motors, what parts of the quickstart code should be removed/changed? For example, getWheelPositions, DriveConstants.TICKS_PER_REV, DriveConstants.WHEEL_RADIUS, etc.

The localization method doesn't really affect the tuning procedure. If you haven't tested your localizer, you should use LocalizationTest or a similar test routine to make sure the positional data is correct. After that, complete the listed steps as detailed in the guide.

Also, in my situation we are not able to install our lateral odometery wheels inline. In our case they are offset from the center line of the robot. What measurements should I use to utilize this configuration?

In that case, StandardTrackingWheelLocalizer may not work for you out-of-the-box, but you can modify the wheel poses passed to the ThreeTrackingWheelLocalizer ctor here. The origin of these coordinates is the center of the robot, and the heading is measured counter-clockwise from the x-axis.

@EddieDL
Copy link
Author

EddieDL commented Oct 20, 2019

Thank you so much for your quick responses. I think this makes sense.

Is it feasible to use dead tracking wheels AND encoders on your DC motors? This seems like it would require 7 DC motor ports on REV Expansion Hubs.

Based on your feedback I will change my question to, is it recommended/required to have encoders for the dead tracking wheels and the DC motors?

While we have the ability to operate other motors with alternate feedback, we would like to not have to tackle this right now. However, if it is the only way to get sufficiently accurate motions with Mechanum wheels, we will need to figure it out. This is our first season using Mechanum wheels so it is a bit of a learning experience :)

@EddieDL
Copy link
Author

EddieDL commented Oct 20, 2019

@rbrott I messed up my last comment, it is now updated correctly.

@rbrott
Copy link
Member

rbrott commented Oct 20, 2019

is it recommended/required to have encoders for the dead tracking wheels and the DC motors?

Neither is required per se. Since you have the tracking wheels already, I would stick with those and try without drive motor feedback.

@EddieDL
Copy link
Author

EddieDL commented Oct 20, 2019

Note to others that might want to do something similar. If you don't plan on using the built-in PID, you need to remove / rpmToVelocity(getMaxRpm())) from the kV configuration in DriveConstraints.java. The value provided from DriveFeedForwardTuner should be used directly.

@rbrott Thanks again, we are getting really close to having something working. Our problem now is turning. It seems like the StandardTrackingWheelLocalizer doesn't use the internal IMU and it seems like our settings for track width are not right. However, when we run the TrackWidthTuner we get a silly number like .35 back.

I am not sure if we should be working to correct our track width or converting the localizer to use the IMU. It seems like if we convert to using the internal IMU there is no point in having the third wheel?

If we should convert to using the IMU, where might we start this process. In the TrackWidthTuner it references we should change the localizer, but it really isn't clear.

PS: When we are all done, we would be happy to create a PR with some updates to the comments. Let me know if you would be interested in that.

@rbrott
Copy link
Member

rbrott commented Oct 21, 2019

Our problem now is turning. It seems like the StandardTrackingWheelLocalizer doesn't use the internal IMU and it seems like our settings for track width are not right.

Have you tried validating that the localizer works correctly with LocalizationTest? Also make sure that DriveConstants.TRACK_WIDTH has a reasonable (i.e., physical) value.

It seems like if we convert to using the internal IMU there is no point in having the third wheel?

Yes, three tracking wheels and an IMU usually results in an overdetermined system. You could use least squares or a more advanced technique to utilize the information (of course you'd have to write your own localizer). Alternatively, you can just drop a wheel.

If we should convert to using the IMU, where might we start this process. In the TrackWidthTuner it references we should change the localizer, but it really isn't clear.

If you're just dropping a wheel, take a look at TwoTrackingWheelLocalizer. Otherwise you'll have to write your own implementation of Localizer.

PS: When we are all done, we would be happy to create a PR with some updates to the comments. Let me know if you would be interested in that.

Sure, I'd be happy to hear any feedback on the tuning instructions and/or general documentation. You can also PR https://github.com/acmerobotics/road-runner-docs.

@EddieDL
Copy link
Author

EddieDL commented Oct 21, 2019

As we understand it, using the 3 wheel localizer is more consistent than using the IMU, for mechanum drivetrains. So we are planning to get the three wheel localizer working. Is our understanding correct that the 3 wheel localizer is better than just an IMU and 2 wheel localizer?

Have you tried validating that the localizer works correctly with LocalizationTest? Also make sure that DriveConstants.TRACK_WIDTH has a reasonable (i.e., physical) value.

We have run LocalizationTest and we have verified the values for X and Y, but I don't think we paid much attention to the heading. We will need to check that out.

Our initial value for DriveConstants.TRACK_WIDTH seemed reasonable to us (we used the measurement between the left and right dead wheels). However, the result from the TrackWidthTunder opmode was very weird. We were also confused by the comment TODO: if you haven't already, set the localizer to something that doesn't depend on drive encoders for computing the heading. Perhaps we are supposed to temporarily set the localizer to the TwoTrackingWheelLocalizer while we are tuning the track width?

Again thanks for all your help!

@rbrott
Copy link
Member

rbrott commented Oct 21, 2019

As we understand it, using the 3 wheel localizer is more consistent than using the IMU, for mechanum drivetrains. So we are planning to get the three wheel localizer working. Is our understanding correct that the 3 wheel localizer is better than just an IMU and 2 wheel localizer?

Unfortunately, I have no personal experience with tracking wheel localizer (only drive wheel localizers). Anecdotally, some prefer 3 wheel localizers because the IMU has additional latency and only updates at 100Hz anyway.

We were also confused by the comment TODO: if you haven't already, set the localizer to something that doesn't depend on drive encoders for computing the heading. Perhaps we are supposed to temporarily set the localizer to the TwoTrackingWheelLocalizer while we are tuning the track width?

That comment cautions against using drive encoders for computing the heading. Neither tracking wheel localizer falls into this camp nor does the default drive encoder localizer (it uses the IMU). The pure drive encoder localizer depends on the value of the track width hence the prohibition.

@EddieDL
Copy link
Author

EddieDL commented Oct 26, 2019

We are generally good on how to use the sample now. I am going to leave the issue open so I can remember to send you a pull request with updated comments/documentation.

I do have a few other questions/issues. I am going to open other issues for those.

Below are the things we think should be address (just so I have it somewhere).

  • Add comment or adjust code for setting kV so that when someone does not want to use internal motor encoders it is obvious to not include / rpmToVelocity(getMaxRpm())).
  • Add some sort of explanation of what impact changing kV, kA, kStatic has and perhaps some "sane" ranges for these.
  • Change StandardTrackingWheelLocalizer to use DriveConstants instead of duplicating values.
  • Provide additional comments about using "non-standard" tracking wheel configuration.
  • Provide additional comments about using only tracking wheels.

@rbrott
Copy link
Member

rbrott commented Oct 26, 2019

OK most of those sound like reasonable additions/clarifications to the documentation.

Change StandardTrackingWheelLocalizer to use DriveConstants instead of duplicating values.

StandardTrackingWheelLocalizer deliberately has a separate set of parameters. Are you suggesting moving them to DriveConstants?

@EddieDL
Copy link
Author

EddieDL commented Oct 26, 2019

What is the reason for the StandardTrackignWheelLocalizer to have a separate set of parameters? Perhaps that is causing some of our issues. Is it for the scenario where you have encoders on all of the drive wheels and dead trailing wheels?

In our scenario we configured all of them the same, which is why I thought they should be the same.

@rbrott
Copy link
Member

rbrott commented Oct 26, 2019

What is the reason for the StandardTrackignWheelLocalizer to have a separate set of parameters?

"Tracking wheels" are dead wheels, not driven wheels (there's no reason to use a tracking wheel localizer for drive encoder localization; that functionality is built into the drive classes). Teams regularly have different encoders, gear ratios, and wheel radii for their dead wheels. I'd be surprised if your driven wheels have exactly the same parameters as your dead wheels.

Is it for the scenario where you have encoders on all of the drive wheels and dead trailing wheels?

Not necessarily. Drive wheel parameters are still required for proper open-loop/feedforward control even if you only use dead wheels for feedback.

@EddieDL
Copy link
Author

EddieDL commented Oct 26, 2019

So in our configuration, we don't have any encoders on the drive wheels. Given this, we configured the TRACK_WIDTH, kV, kA, kStatic, WHEEL_RADIUS, etc. in `DriveConstants' based on our dead wheels. Perhaps this was wrong thinking on our part?

@rbrott
Copy link
Member

rbrott commented Oct 26, 2019

Yes, that's incorrect. Those parameters should always refer to the drive wheels; many are used for feedforward.

@EddieDL
Copy link
Author

EddieDL commented Oct 26, 2019

I guess it is confusing to me. How those would work if we aren't getting feedback from the encoders. How would you even calculate them since here is no feedback?

@rbrott
Copy link
Member

rbrott commented Oct 26, 2019

You'll want to tune the feedback with the drive encoders plugged in. If your motors do not have encoders, you'll have to tune it manually with the dashboard with TurnTest (adjust until the robot turns the proper angle).

@EddieDL
Copy link
Author

EddieDL commented Oct 26, 2019

Ahh... So does the following sound like a reasonable sequence of actions?

  1. Plug in all of the drive wheel encoders.
  2. Remove the custom localizer.
  3. Tune the kV, kA, kStatic and ensure all settings in DriveConstants apply to the drive wheels.
  4. Disconnect the drive encoders and connect the dead wheel encoders.
  5. Ensure your localizer configuration matches your dead wheels.
  6. Configure your custom localizer.
  7. Tune your PID.

@rbrott
Copy link
Member

rbrott commented Oct 26, 2019

That seems more-or-less reasonable. Have you checked out this list?

@EddieDL
Copy link
Author

EddieDL commented Oct 26, 2019

Yup. That is the process we have been using.

It seems like our main remaining issue is that we were not tuning the kV, kA, kStatic, and TRACK_WIDTH for the driven wheels. We did it based on the Localizer data or something (we haven't had the drive encoders plugged in).

Though, with all of the issues we are considering just using the encoder ports so we can just use the built in velocity PID. Our first competition is next weekend :)

@EddieDL
Copy link
Author

EddieDL commented Oct 28, 2019

@rbrott two more questions.

  • What are the units on Max Velocity, Max Acceleration, and Jerk. My assumption is Inches per second, and Inches per second per second for Max Velocity and Max Acceleration, but Jerk I have no idea.
  • If we choose to not use the encoders from the drive wheels what should getWheelPositions return? We did convert that to return the positions from the Localizer, which is why we thought we needed to make the DriveConstants the same as the Localizer.

@rbrott
Copy link
Member

rbrott commented Oct 29, 2019

What are the units on Max Velocity, Max Acceleration, and Jerk. My assumption is Inches per second, and Inches per second per second for Max Velocity and Max Acceleration, but Jerk I have no idea.

The units of velocity, acceleration and jerk are in/sec, in/sec^2, and in/sec^3, respectively (keep in mind you can substitute any distance unit you like; the quickstart tacitly assumes inches).

If we choose to not use the encoders from the drive wheels what should getWheelPositions return?

getWheelPositions() should always return the positions of the drive wheels. If you don't have drive encoders/don't plan to use them, you can return a list of zeroes with the proper length.

@Calvin-Xu
Copy link

Calvin-Xu commented Nov 1, 2019

is it recommended/required to have encoders for the dead tracking wheels and the DC motors?

Neither is required per se. Since you have the tracking wheels already, I would stick with those and try without drive motor feedback.

So is it that when an alternate localizer (i.e. StandardTrackingWheelLocalizer) is set, the error in the drivetrain PID loop is then derived from the position the localizer returns instead of the drive wheel positions, which renders encoders on the drive motors unnecessary (or are there still velocity control benefits)? We are just recently beginning to understand the process (related); it would be great that we do not need seven encoder ports just for the drivetrain.

@rbrott
Copy link
Member

rbrott commented Nov 1, 2019

The localizer determines how the robot's position is computed. The default localizers use the drive wheel encoders. This position is used by the various followers, including the PIDVA follower.

This is independent of the onboard/built-in motor velocity PID that is recommended for drive encoders if available.

If you need to reclaim encoder ports, it's probably better to sacrifice velocity control (i.e., remove the drive wheel encoders). That said, velocity control is useful in addition to just position control; in essence, it helps prevent velocity error from "spilling"/"transforming" into position error.

@Calvin-Xu
Copy link

Calvin-Xu commented Nov 1, 2019

So if I understand correctly, the goal of both drive characterization with DriveFeedforwardTuner and drive wheel encoders + tuning with DriveVelocityPIDTuner is to establish a relationship between power set to the motor and velocity of the drive, and the latter is preferable to the former?

That said, velocity control is useful in addition to just position control;

Would you elaborate in the distinctions between position control and velocity control in the context of roadrunner? We have been visualizing PID in 1D scenarios, and imagine that the controller makes changes to the velocity based on the error computed from position—how are the two quantities controlled separately? We are probably not familiar with how the followers work, and how they use position—some explanation would be very helpful!

@rbrott
Copy link
Member

rbrott commented Nov 2, 2019

So if I understand correctly, the goal of both drive characterization with DriveFeedforwardTuner and drive wheel encoders + tuning with DriveVelocityPIDTuner is to establish a relationship between power set to the motor and velocity of the drive, and the latter is preferable to the former?

Yes, that's the essence of their function. The goal is to translate wheel/shaft velocities into motor voltages. This can be accomplished with feedforward/open-loop control based on the (idealized) linear relationship between voltage and velocity (this can be augmented by considering acceleration and static friction through kA and kStatic), or it can be accomplished with feedback/closed-loop control by manipulating the voltage to achieve the desired velocity. The later feedback mechanism is preferable due to its robustness to changes in input voltages, friction, and other unmodeled effects/dynamics.

Would you elaborate in the distinctions between position control and velocity control in the context of roadrunner? We have been visualizing PID in 1D scenarios, and imagine that the controller makes changes to the velocity based on the error computed from position—how are the two quantities controlled separately? We are probably not familiar with how the followers work, and how they use position—some explanation would be very helpful!

The position and velocity controllers form a cascade where the output of the position controller becomes the input for the velocity controller. In this case, the position controller manipulates velocity to affect position error, and the velocity controller manipulates applied voltage to affect velocity error.

The trajectory followers are controllers that compute the robot's velocity and acceleration from the current trajectory and current position (they fall into the category of reference trackers). Some of the followers in Road Runner use PID with VA feedforward terms (the holonomic PIDVA trajectory follower source is pretty readable and understandable at a high level) while others use more sophisticated techniques.

@EddieDL
Copy link
Author

EddieDL commented Nov 13, 2019

@rbrott thanks again for all of your help. I am going to continue to keep this open so it reminds me to work on some suggested improvements to the docs (not sure if there is a better way to manage that).

We still have problems with the tuning, but I am going to open a separate issue about that.

@Calvin-Xu thank you for your addition to this thread, you asked some great questions that helped me understand this from a different perspective.

@shishghate
Copy link

Ahh... So does the following sound like a reasonable sequence of actions?

  1. Plug in all of the drive wheel encoders.
  2. Remove the custom localizer.
  3. Tune the kV, kA, kStatic and ensure all settings in DriveConstants apply to the drive wheels.
  4. Disconnect the drive encoders and connect the dead wheel encoders.
  5. Ensure your localizer configuration matches your dead wheels.
  6. Configure your custom localizer.
  7. Tune your PID.

@EddieDL , We are also embarking down this path, and did these steps work for you? You also mentioned that your encoders were not on center. Were you able to get them to work with a non 0 x position?

@rbrott rbrott closed this as completed Mar 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants