|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
| Thread Tools | Rate Thread | Display Modes |
|
#31
|
|||||
|
|||||
|
Re: Team 254 2011 FRC Code
In light of the fact that the Victor's inputs are highly discretized by the Victor itself (see http://www.vexforum.com/showthread.php?t=20350), a small lookup table (mapping PWM duty cycle<->speed) will ultimately provide the best possible accuracy, and will be computationally inexpensive to run. If you look under the hood of the WPIlib PWM code, all continuous-valued speed commands are ultimately converted to a PWM duty cycle value between 1 and 255 (0 is a reserved value for holding the line low). The effective duty cycle for the Victor is then .665ms + X*6.525us, where X is the PWM value. Since there are only 255 unique values, at most you need 255 elements in your lookup table (and in actuality, the beginning and end of this list will be past the Victor's 1.0 to 2.0ms allowable input range spec anyhow).
Define a float/double array with 255 values. The index is the PWM value; the value is the actual speed for that value. To populate this array you could, for example, run a "sweep" of the Victor by running a motor at each possible value for a couple of seconds and recording the total distance traveled during each segment (you would want to filter this data to preserve monotonicity). It would take several minutes to run, but you only need to do it once (when I get a chance, I will take an old bot and do exactly this, and post the results). Driving the Victor would be accomplished by searching through the 255 value array for your desired speed and selecting the index of the closest value in the array. Using a nearest-value binary search (since the array ought to be sorted) would require only 9 comparisons*, worst case, to select the optimal PWM value from the array. Using this method, you are guaranteed to have the least possible linearization error, though the polynomial method is close enough that I doubt you'd notice the difference. *At most 8 comparisons are necessary to search a 255 element array (since worst case complexity is O(log2(n)), but you would want an extra comparison to check if the adjacent value in the array is actually closer, since the easiest way to write a nearest-value binary search would be to find the closest value that is always either > or < the input. |
|
#32
|
||||
|
||||
|
Re: Team 254 2011 FRC Code
Would this work? - Apply joystick commands -127 to 0 to 127 and measure the Vic's output voltage1 for each one. - Normalize those measured voltages to the (floating-point) range -127.0 to 0 to +127.0 - From this data, for each desired whole number output (in the range -127 to +127), determine (by simply looking at the measured data)2 the integer value required to come nearest to the desired output. Put these integers into an array (-127 to +127). - The index of the array is the output you want (-127 to +127), and the value stored at that index is the value you should command. No lookup search or interpolation required. 1 stalled? or free? probably makes a difference. not sure whether you want average or rms voltage. 2 or just let a spreadsheet do it for you |
|
#33
|
|||||
|
|||||
|
Re: Team 254 2011 FRC Code
Quote:
If that isn't splitting hairs, though, I don't know what is. |
|
#34
|
|||
|
|||
|
Re: Team 254 2011 FRC Code
I feel the need to quote this to emphasize it. Someone on 254 this year had a huge lookup table to do just this, but, as far as I could tell, didn't filter the data. The result was a bit inconsistent, and we went back to the polynomial.
To do it really right, I want to take a victor, battery, CIM, and a dynamometer, and generate data points for various different operating points. (Use 16 speeds and 16 PWM values.) Not sure where I can get access to a dynamometer though. I have noticed that in practice, for example, if you are going forwards, and apply a tiny bit of backwards power, the entire drivetrain locks up. |
|
#35
|
|||||
|
|||||
|
Re: Team 254 2011 FRC Code
Quote:
The drive locking up when you apply a bit of reverse power makes perfect sense given that the motor controller has an internal H bridge. When you switch directions, it's as if you are in "brake mode". This can be very useful for stopping on a dime in auto mode. |
|
#36
|
|||
|
|||
|
Re: Team 254 2011 FRC Code
Hi,
Thanks for posting your code. The architecture is very pleasing to a controls engineer. I like control loops and filters as classes. Can you expand a little on your use of negitive inertia. I assume this is equivalent to adding derivatives of the control input to improve performance, but I would like to hear more about your use. Any papers to refererence? Also, I think you can use much simpler functions to fit your Victors. One linearizer that involves a single parameter to adjust is: vic_cmd = min_cmd/(1 - (1-min_cmd)*input_cmd) where min_cmd = the minimum command to keep the motor moving, i.e. equivalent to the torque required to overcome dynamic friction. All commands are normalized [-1,1]. One can play with min_cmd to get a very good fit. The equation is valid for input_cmd>0. You have to change a few signs for input_cmd<0 and the min_cmd can be different for each sign. This equation follows directly from the steady state current model of the h_bridge with a low frequency pwm. The current model is summarized in this older post. I will write a blog post on this later. Attached is a curve fit of some old data I had on a victor. Maybe Joe Ross sent it to me and it could be an 883 or 884. The inverse is obtained by taking the victor speed and running it through the inverse function above. Last edited by vamfun : 17-02-2012 at 17:06. |
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|