#444: Add V5 IMU Wrapper Class#452
Conversation
Octogonapus
left a comment
There was a problem hiding this comment.
This is approved pending CI passes and a kernel bug fix.
theol0403
left a comment
There was a problem hiding this comment.
Just some tiny nits. Otherwise looks good.
All axes return an angle in the range of -180 to 180
Imo I don't think this is nice to use. You have to deal with the input to your control algorithms jumping if you don't constrain the angle after you do any setpoint-reading calculations. The IMU can return an unconstrained range through a different API method, which might be nicer to use. Up to you two, it's not a huge deal either way.
| */ | ||
| IMU(std::uint8_t iport, IMUAxes iaxis = IMUAxes::z); | ||
|
|
||
| virtual ~IMU(); |
There was a problem hiding this comment.
Explicitly defining a virtual destructor isn't needed as it inherits the virtual destructor from base classes.
There was a problem hiding this comment.
ADIGyro probably shouldn't have one, either.
| * | ||
| * @return The current sensor value or `PROS_ERR`. | ||
| */ | ||
| double getAcceleration(); |
| return PROS_ERR; | ||
| } | ||
|
|
||
| if (angle > 180 || angle < -180) { |
There was a problem hiding this comment.
This functionality matches the recently added okapilib helper functions to constrain an angle to 180 degrees. Perhaps use those instead?
|
When I was developing this class, I settled on the [-180, 180] range for a couple of reasons. First, the PROS API for the IMU is pretty limited. I don't believe there is a command which gives me an unbounded rotation for all 3 axes. In my testing, The second reason I chose this range was to match the existing gyro better. I would need to test the ADIgyro again, but I believe its range is [-1800,1800]. In order to retain some compatibility, I wanted these to use the same general tracking behavior. It is possible to implement unbounded counting in software, but I believe we should then update ADIgyro as well to reflect this behavior change. Consistent behavior will be needed for my next project of adding a gyro to odometry. |
|
Sounds good. Did you want to use for the angle wrapping? I'm sure you could also move the function tomathUtil.hpp which puts the function in a centrally available place. Doing this has the added benefit of being able to remap values which require more than 360 degrees of correction.
|
|
I agree with Theo, I think moving that function to |
|
I'm a little confused by this. Is the proposal to make the IMU and ADIgyro class return unbounded rotation values, and then convert that using |
I believe the proposal is to use |
|
In that case, the next step is to remove |
No. We can't break backward compatibility. |
|
I must first apologize. I think I am more confused than before. Looking at differences between ADIGyro and IMU, IMU |
|
Sorry for any confusion, all I was saying was to replace if (angle > 180 || angle < -180) {
angle += std::copysign(360, offset);
}with angle = constrainAngle180(angle);to remove code duplication. |
|
Ok, that makes sense. As to the lack of angle wrapping, should I spend a bit of time and make the IMU return unbounded by default? The existing ADIgyro returns unbounded. I'm a little worried that if these two don't match, our upcoming project to implement gyro based odometry may become difficult. |
I still am against supporting (by default) odometry incorporating the ADI gyro. I don't think it's worth you putting in the extra work here to match that functionality. We'd probably want to convert back to a bounded angle anyway. |
c4d4111
|
Implemented the suggestion from @theol0403 . I would like to give it a test, but if it works and there are no further concerns. I think this is ready for review. |
|
Looks good. Ideally the |
|
I am fine with leaving it in odomMath. I pushed an update to fix the return value from |
|
Just gave the latest code a test, works as expected. |
# Conflicts: # include/okapi/impl/device/rotarysensor/adiGyro.hpp # src/impl/device/rotarysensor/adiGyro.cpp
a8be2f8 to
c62fe1c
Compare
|
@invalidflaw or @kunwarsahni01 can one of you please test the IMU, especially calibration? |
|
I'll give it a try tomorrow morning. |
|
Just tested this morning. The IMU works as expected. Calibration and IMU disconnect are handled properly. |
Description of the Change
Adds a new wrapper class derived from ContinuousRotarySensor for the V5 IMU. The constructor accepts a V5 port number and an enum axis definition to measure. The z(yaw) axis is configured as default. All axes return an angle in the range of -180 to 180, much like the existing ADIgyro class does. To measure more axes, separate IMU instances should be made by the user.
As suggested in the issue, a value, "offset" is used to reset the sensor. The PROS API does not allow for an easy zero process, so the
IMU::reset()command will change the offset parameter to match the current measured angle. In the event of anIMU::get()command occurs outside the range of -180 to 180, the offset is inverted by adding -360*(offset/sign(offset)) to the original offset.Because the reset command does not calibrate the IMU, I added an
IMU::calibrate()method. The constructor does not call this as the v5 port is automatically configured and is calibrated on brain startup. Any further calibration should be controlled by the user.Because the IMU is an accelerometer as well as a gyro, I added an
IMU::getAccl()command to retreive the acceleration value along the instanced axis.Motivation
Adding a wrapper class for the IMU will allow it to be integrated into odometry and chassis models at a later date. Implementing the sensor within okapi allows users to program their robot using the same namespace.
Possible Drawbacks
The V5 IMU chooses one of 6 orientations based on the calibration process, then assigns the XYZ axes accordingly. I am unsure how/if this should be documented.
Verification Process
I placed the IMU on a robot chassis read the gyro data using the PROSC API and the new IMU class. Both classes returned the same euler angles.
To test the reset function, I set the IMU to measure robot yaw. I started the program, and rotated the chassis 90 degrees, after which I pressed a button on my controller which was set to run the reset function. After doing so, the robot continued to read -180 to 180 with the 0 now located at the original 90 degrees.
Applicable Issues
Closes #444