We have a mechanism (arm) that we are using a Rev Through-Bore Encoder to determine the angle of. In absolute mode, we can determine its position at boot-up, removing the need for the drive team to home it before each match. The issue is that it wraps from 0 - 1. Our arm has a safe operating range of ± 180 degrees from facing forwards, if it goes beyond this electrical cables get wrapped up. Our software is configured so that it knows it cannot go lower than 0 or greater than 1, and we’re using a PID loop for position. We find that when we go from a point close to one end of its range of motion (such as +175 degrees), then set it to the other end (such as -175 degrees), sometimes it “overshoots” its position, causing the encoder to wrap around (goes from -179 deg to +181 deg). This causes the PID loop to try and compensate by going around again, which the wires don’t physically allow for. The absolute encoder does not continuously accumulate, preventing it from knowing it needs to go the “shorter” way around.
These are our current solutions
Using the absolute through-bore encoder for position PID feedback (as described above, sometimes leads to unsafe conditions)
Using the through-bore encoder to ‘home’ the relative encoder on boot, then using the relative encoder for position PID feedback (significant backlash in the gearbox and chain makes this inaccurate)
Connect the absolute duty-cycle output of the through-bore encoder to a RaspberryPi, and connect the relative quadrature (which accumulates continuously, I believe) to the Spark Max. On boot up, home the relative input on the Spark Max with the absolute signal on the RaspberryPi, then use the relative signal on the Spark Max from there. (Is this technically possible?) (and can the Pi be cut out of this, sending both the relative and absolute data to the Spark Max?)
Use a PID loop running on the RoboRIO, and handle wrapping there (CAN latency and a slow robot periodic loop makes this undesireable)
Should be a easy fix fortunately. The SparkMax supports PID wrapping. This is the same as the WPILib continuous mode in the PID API. There are three parameters to set in the device.
This sounds exactly what I need as well. But since REV documentation is lacking on how these settings exactly work I’ll ask some questions for clarification.
We have an arm, it’s zero degree position is parallel to the ground. 90 degree is straight up and 180 is opposite.
Any negative degree is the arm starting to rotate through the robot (BAD).
So -90 would be straight down through the bottom of the robot.
We are using SparkMax onboard positional PID. Works great. But yes, if we were to start the arm at -178 degrees for example and had it seek 10 degrees it would want to rotate through the robot to get there. Because it wants to make -178 go to -170 then -90, -45 etc. until 0 then go to 10.
Of course I want it to go from -170 and wrap to 180 then go to 10.
The arm can technically be safe at anywhere from -10 degrees to -170 degrees.
so [-170…90…0…-10] are safe angles.
So you are saying that if I turn on PID wrapping and start the robot at -170 and tell it to seek like 45 degrees it will first seek to go to 180 and then go to 45?
When both edges of the safe angles are negative numbers what are the Min and Max input? Is my min -170 and max 180? That seems strange because all the angles between -170 and 180 are not achievable.
Okay I may have misread some of the initial problem statement… So this mode simply treats the min and max inputs as the same point. So you’ll still need to be careful here. It will always go in the direction that will be ‘shortest’. So in your case, going from -10 to -170, the shortest path with PID wrapping will still be -10 → -50 → -100 → -170.
Current put your zero/360 degree point at an inobtainable spot, and set your through bore encoder to 0-360 then put hard limits in the code at the danger zones then you never have to worry about it’s wrapping around
This is likely the better solution, is you have a limited range. You can also do this with the SparkMax. Have some calibration where you read out the sensor offset that you want, then set the zero point using the API.
However for OP, with +/- 180 degree range, this also will not work.
For OP:
How about connecting both signals of the through bore to the roboRIO, the absolute and the quadrature. Then, on boot, set the quadrature value to that of the absolute sensor. Then just run a PID loop on the RIO using the quadrature sensor, which will not wrap. This will require 3 DIOs, but should do what you want without latency or backlash effects.
I belive this will Require a scaling factor? At least it did for us when we ran the two sensors in combination And make sure there is no risk of jumping a tooth etc otherwise you may run into problems if jumping a tooth is an issue you may be able to run a syncing command that periodically rysncs the two sensors, or put the rysync on a button for the operator to press if they become out of line:
Better yet, maybe run a statement saying if the hall sensor is greater then a x diffrence from the absolute automatically rysnc to absolute encoder
Again this is assuming the OP would still like to use the Through-Bor for reference since it gives you the option to correct if somthing were to get them out of sync during a match, we did run this setup until we moved our zero point out of range
No I don’t think so, since you can’t do both a quadrature encoder and a duty cycle encoder at the same time (unless it was a brushed motor).
I assume your concern is about wiring distance or adding more cables to the harness, which is fair.
If you haven’t already, it may be worth at least trying the built-in sensor in the NEO just to see if the performs well enough for your needs.
Yes, if I understand what he is saying it can be done going through the spark max as you can getting reading from both the absolute and hall,
I think you misunderstood slightly. I was suggesting using both the quadrature and absolute of the through bore sensor, since it is capable of both. Not the NEO sensor.
So the through-bore is capable of outputting absolute and quadrature at the same time? I assume it is because the pinout does not conflict in the wire (separate A/B/I and ABS wires).
Upon trying to do this through the CAN Spark Max, I got an error because it doesn’t want to instantiate an absolute and alternate encoder on the same object (for some reason).
I may go with the Pi solution for our competition, just splice the abs duty cycle line to the pi and read that on boot.