patternMinor
Generating Position
Viewed 0 times
generatingpositionstackoverflow
Problem
I'm written the following code to calculate the position of a motor during each timestep, the result of which will be compared with feedback from a quadrature encoder and subjected to a PID algorithm. The trajectory will follow a trapezoidal profile. i.e. Accelerate to a maximum velocity, coast and then decelerate to the target position:
How can the accuracy of the algorithm be improved?
program ideone;
VAR
Pos : Real;
Vel : Real;
Acc : Real;
Demand : Real;
Max_Vel : Real;
AccDist : Real;
DecelPoint : Real;
Error : Real;
begin
Pos:=0;
Vel:=0;
Acc:=5;
Demand:=150;
Max_Vel:=10;
AccDist := (Max_vel/Acc * Max_vel) / 2;
DecelPoint := Demand - AccDist;
Writeln('AccelDist ',AccDist:5:2);
Writeln('DecelPoint ',DecelPoint:5:2);
Writeln('ACCEL');
While Vel <> Max_vel
Do Begin
Pos := Pos + Vel + Acc/2;
Vel := Vel + Acc;
If Vel >= Max_Vel
Then Begin
Vel := Max_Vel;
Pos := AccDist
End;
Writeln('Position:',Pos:5:2);
End;
Writeln('FLAT');
While Pos 0
Do Begin
If Error > 0
Then Begin
Pos := DecelPoint;
Error := 0;
End;
Pos := Pos + Vel - Acc/2;
Vel := Vel - Acc;
If Vel <= 0
Then Pos := Demand;
Writeln('Position:',Pos:5:2);
End;
end.How can the accuracy of the algorithm be improved?
Solution
First things first. Pascal is a very readable language, if written clearly. One of the main reasons of writing Pascal is because you want readable code. I'll start with some styling and naming, the actual calculations will be handled in the second part.
Style
Regardless of which standard you follow, make sure you're consistent. I'm following the GNU Pascal Coding Standards.
Keywords are lower-case
No capitals. Although Pascal accepts the keywords as valid regardless of capitalisation, it's good style to follow the standard.
If then
Keep your
Indentation
Your code isn't indented. Indentation is a major step forward in readability.
Spaces
A single space goes before and after operators. There are also spaces after commas.
Semi-colons
You are missing a
Variable naming
Your variable names could use some love. You may think
Result
I've fixed the above (except part of the naming, I'm not too good at that either). The result:
Algorithm
Increasing the accuracy of the graph is a matter of increasing the amount of measurements. If every second isn't good enough, measure every half a second. If that's still not good enough, measure every tenth of a second. Or whatever your time unit may be. Your current set-up does not allow for such modifications.
You'll either need a
Style
Regardless of which standard you follow, make sure you're consistent. I'm following the GNU Pascal Coding Standards.
Keywords are lower-case
var while do if then begin endNo capitals. Although Pascal accepts the keywords as valid regardless of capitalisation, it's good style to follow the standard.
If then
Keep your
if and then on the same line.if Error > 0 thenIndentation
Your code isn't indented. Indentation is a major step forward in readability.
Spaces
A single space goes before and after operators. There are also spaces after commas.
Semi-colons
You are missing a
; here:Pos := AccDistVariable naming
Your variable names could use some love. You may think
Pos is a good name for a position, but Pos() is also an already existing function in Pascal. Your variable has nothing to do with the function, so avoid the confusion.DecelPoint is according to the standard. Max_Vel isn't.Result
I've fixed the above (except part of the naming, I'm not too good at that either). The result:
program ideone;
var
Pos : Real;
Vel : Real;
Acc : Real;
Demand : Real;
MaxVel : Real;
AccDist : Real;
DecelPoint : Real;
Error : Real;
begin
Pos := 0;
Vel := 0;
Acc := 5;
Demand := 150;
MaxVel := 10;
AccDist := (MaxVel / Acc * MaxVel) / 2;
DecelPoint := Demand - AccDist;
Writeln('AccelDist ', AccDist:5:2);
Writeln('DecelPoint ', DecelPoint:5:2);
Writeln('ACCEL');
while Vel <> MaxVel do
begin
Pos := Pos + Vel + Acc / 2;
Vel := Vel + Acc;
if Vel >= MaxVel then
begin
Vel := MaxVel;
Pos := AccDist;
end;
Writeln('Position:',Pos:5:2);
end;
Writeln('FLAT');
while Pos 0 do
begin
if Error > 0 then
begin
Pos := DecelPoint;
Error := 0;
end;
Pos := Pos + Vel - Acc / 2;
Vel := Vel - Acc;
if Vel <= 0 then
Pos := Demand;
Writeln('Position:', Pos:5:2);
end;
end.Algorithm
Increasing the accuracy of the graph is a matter of increasing the amount of measurements. If every second isn't good enough, measure every half a second. If that's still not good enough, measure every tenth of a second. Or whatever your time unit may be. Your current set-up does not allow for such modifications.
You'll either need a
MaxNumIterations and divide the whole course over that or put in a modifier which does basically the same under water. I'd go with the first.Code Snippets
var while do if then begin endif Error > 0 thenPos := AccDistprogram ideone;
var
Pos : Real;
Vel : Real;
Acc : Real;
Demand : Real;
MaxVel : Real;
AccDist : Real;
DecelPoint : Real;
Error : Real;
begin
Pos := 0;
Vel := 0;
Acc := 5;
Demand := 150;
MaxVel := 10;
AccDist := (MaxVel / Acc * MaxVel) / 2;
DecelPoint := Demand - AccDist;
Writeln('AccelDist ', AccDist:5:2);
Writeln('DecelPoint ', DecelPoint:5:2);
Writeln('ACCEL');
while Vel <> MaxVel do
begin
Pos := Pos + Vel + Acc / 2;
Vel := Vel + Acc;
if Vel >= MaxVel then
begin
Vel := MaxVel;
Pos := AccDist;
end;
Writeln('Position:',Pos:5:2);
end;
Writeln('FLAT');
while Pos < DecelPoint do
begin
Pos := Pos + Vel;
Writeln('Position:', Pos:5:2);
end;
Error := Pos - DecelPoint;
Writeln('DECEL');
while Vel > 0 do
begin
if Error > 0 then
begin
Pos := DecelPoint;
Error := 0;
end;
Pos := Pos + Vel - Acc / 2;
Vel := Vel - Acc;
if Vel <= 0 then
Pos := Demand;
Writeln('Position:', Pos:5:2);
end;
end.Context
StackExchange Code Review Q#97747, answer score: 3
Revisions (0)
No revisions yet.