View Single Post
  #14   Spotlight this post!  
Unread 03-12-2011, 00:53
otherguy's Avatar
otherguy otherguy is offline
sparkE
AKA: James
FRC #2168 (The Aluminum Falcons)
Team Role: Mentor
 
Join Date: Feb 2010
Rookie Year: 2009
Location: CT
Posts: 434
otherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to behold
Re: Team 254 2011 FRC Code

Quote:
Originally Posted by Ether View Post
Did you do an analysis to determine whether the piecewise linear code plus the conditional logic it requires executes faster than the single polynomial ?

If speed is what you need, it's hard to beat a complete lookup table (no interpolation required):

http://www.chiefdelphi.com/forums/sh...1&postcount=12

They aren't using a single polynomial, they're using a 5th order poly and 7th order poly, then averaging the two.

The only reason I asked the question is because I looked at their code, and it seemed pretty involved for something that needs to be calculated every time you want to send an output to a motor controller.

Code:
double RobotState::victor_linearize(double goal_speed)
{
	const double deadband_value = 0.082;
	if (goal_speed > deadband_value)
		goal_speed -= deadband_value;
	else if (goal_speed < -deadband_value)
		goal_speed += deadband_value;
	else
		goal_speed = 0.0;
	goal_speed = goal_speed / (1.0 - deadband_value);

	double goal_speed2 = goal_speed * goal_speed;
	double goal_speed3 = goal_speed2 * goal_speed;
	double goal_speed4 = goal_speed3 * goal_speed;
	double goal_speed5 = goal_speed4 * goal_speed;
	double goal_speed6 = goal_speed5 * goal_speed;
	double goal_speed7 = goal_speed6 * goal_speed;

	// Constants for the 5th order polynomial
	double victor_fit_e1		= 0.437239;
	double victor_fit_c1		= -1.56847;
	double victor_fit_a1		= (- (125.0 * victor_fit_e1  + 125.0 * victor_fit_c1 - 116.0) / 125.0);
	double answer_5th_order = (victor_fit_a1 * goal_speed5
					+ victor_fit_c1 * goal_speed3
					+ victor_fit_e1 * goal_speed);

	// Constants for the 7th order polynomial
	double victor_fit_c2 = -5.46889;
	double victor_fit_e2 = 2.24214;
	double victor_fit_g2 = -0.042375;
	double victor_fit_a2 = (- (125.0 * (victor_fit_c2 + victor_fit_e2 + victor_fit_g2) - 116.0) / 125.0);
	double answer_7th_order = (victor_fit_a2 * goal_speed7
					+ victor_fit_c2 * goal_speed5
					+ victor_fit_e2 * goal_speed3
					+ victor_fit_g2 * goal_speed);


	// Average the 5th and 7th order polynomials
	double answer =  0.85 * 0.5 * (answer_7th_order + answer_5th_order)
			+ .15 * goal_speed * (1.0 - deadband_value);

	if (answer > 0.001)
		answer += deadband_value;
	else if (answer < -0.001)
		answer -= deadband_value;

	return answer;
}

They clearly have a handle on things, so I was wondering if this approach provided them something over what I teach my kids (the piecewise linear approach described previously)

here's the code one of my kids came up with as part of a pre-season homework assignment a few weeks ago. "scale" is a 2d array of points characterizing the piecewise function. The benefit of implementing it this way is that you can modify your array of points at any time, to tweak behavior, without having to modify your code.
Code:
    static double getInterpolatedAxis(double input){
        for(int i=0;i<scale.length-1;i++){
             if(input<scale[i][0]&&input>scale[i+1][0]){
                double slope=(scale[i+1][1]-scale[i][1])/(scale[i+1][0]-scale[i][0]);//get slope
                double intercept = (-1*slope*scale[i][0])+scale[i][1];
                return (slope*input)+intercept;
            }
        }
    }
Anyone who's been through an Algebra 1 class should be able to quickly grasp the math. Added bonus of them getting to apply existing classroom knowledge.