Posted 30 May 2024
While looking through the code for another reason, I discovered that I have committed the mortal sins of using the same name for a global variable, a local variable and a function definition parameter. Originally I defined global variables gl_Leftspeednum & gl_Rightspeednum thusly:
1 2 |
uint16_t gl_Leftspeednum = MOTOR_SPEED_HALF; uint16_t gl_Rightspeednum = MOTOR_SPEED_HALF; |
But then some years later in my code I see:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
void RunBothMotorsMsec(bool bisFwd, int timeMsec = 500, int gl_Leftspeednum = MOTOR_SPEED_HALF, int gl_Rightspeednum = MOTOR_SPEED_HALF); rightSpdnum = (rightSpdnum <= MOTOR_SPEED_HALF) ? rightSpdnum : MOTOR_SPEED_HALF; //result can still be neg gl_Rightspeednum = (rightSpdnum > 0) ? rightSpdnum : 0; //result here must be positive leftSpdnum = (leftSpdnum <= MOTOR_SPEED_HALF) ? leftSpdnum : MOTOR_SPEED_HALF;//result can still be neg gl_Leftspeednum = (leftSpdnum > 0) ? leftSpdnum : 0; //result here must be positive void MoveAhead(int gl_Leftspeednum, int gl_Rightspeednum) MoveAhead(gl_Leftspeednum, gl_Rightspeednum); void MoveReverse(int gl_Leftspeednum, int gl_Rightspeednum) MoveReverse(gl_Leftspeednum, gl_Rightspeednum); SetLeftMotorDirAndSpeed(true, gl_Leftspeednum); SetRightMotorDirAndSpeed(true, gl_Rightspeednum); void RunBothMotors(bool bisFwd, int gl_Leftspeednum, int gl_Rightspeednum) RunBothMotors(bisFwd, gl_Leftspeednum, gl_Rightspeednum); //reversed 01/11/22 - 01/14/22 - reversed it back again gl_Leftspeednum = initleftspeed + IRHomingOutput; gl_Rightspeednum = initrightspeed - IRHomingOutput; //gl_pSerPort->printf("gl_Left/Rightspeednum = %d / %d\n", gl_Leftspeednum, gl_Rightspeednum); //limit wheel speeds to valid range (0-255) gl_Leftspeednum = (gl_Leftspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : gl_Leftspeednum; gl_Leftspeednum = (gl_Leftspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : gl_Leftspeednum; gl_Rightspeednum = (gl_Rightspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : gl_Rightspeednum; gl_Rightspeednum = (gl_Rightspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : gl_Rightspeednum; |
They’re everywhere! yikes!
So, what to do? The original (bad) idea was to have these variables ‘global’ so any part of the code could ‘see’ the current motor speeds. This was BAD because that also meant that any part of the code could change the motor speed (even if it shouldn’t) , and figuring out who did that would be a nightmare. This is where I should have started thinking about building a ‘motor’ class to hide all this – but I didn’t, so….
Also, using a global symbol name in a function definition is at least moronic if not suicidally stupid – does that overwrite the original declaration? To add insult to injury, the function definitions above use ‘int’ as the type rather than ‘uint_16’, so does that mean that motor speed can be negative, but just inside that function – ouch, my head hurts!
Alright – since I didn’t do the right thing and encapsulate this stuff in a motor class, and I don’t want to have to rewrite the entire 7K+ line program (at least not yet), I need to figure out a short-term non-idiotic fix (or maybe just close my eyes and have another beer?)
OK, so the functions involved in this debacle are:
- void SetLeftMotorDirAndSpeed(bool bIsFwd, int speed)
- void SetRightMotorDirAndSpeed(bool bIsFwd, int speed)
- void RunBothMotors(bool bisFwd, int gl_Leftspeednum, int gl_Rightspeednum)
- RunBothMotorsBidirectional(int leftspeed, int rightspeed)
- void RunBothMotorsMsec(bool bisFwd, int timeMsec = 500, int gl_Leftspeednum = MOTOR_SPEED_HALF, int gl_Rightspeednum = MOTOR_SPEED_HALF)
- void RunBothMotorsMsec(bool bisFwd, int timeMsec, int gl_Leftspeednum, int gl_Rightspeednum)
- void MoveReverse(int gl_Leftspeednum, int gl_Rightspeednum)
- void MoveAhead(int gl_Leftspeednum, int gl_Rightspeednum)
SetLeft/RightMotorDirAndSpeed(bool bIsFwd, int speed):
This declaration should probably be (bool, uint16_t) as negative speed values aren’t allowed. I changed the speed declaration from ‘int’ to ‘uint16_t’ and the program still compiles OK. The ‘speed’ argument gets passed to ‘AnalogWrite’ which is declared as AnalogWrite(int pin, int value).
RunBothMotors(bool bisFwd, int gl_Leftspeednum, int gl_Rightspeednum):
RunBothMotors() is called just once in the code, by RunBothMotorsMsec(). RunBothMotorsMsec() in turn is called just four times – three times by HandleExcessSteervalCase() and once by RunToDaylight(). In all four cases the speed arguments are positive constant integers <= 1000 (Teensy analog output resolution is set at 12 bits –>4096). It looks like RunBothMotors() and RunBothMotorsMsec() should declare their speed arguments to be uint16_t
RunBothMotorsBidirectional(int leftspeed, int rightspeed)
RunBothMotorsBidirectional(int leftspeed, int rightspeed) just calls SetLeftMotorDirAndSpeed() however, the speed arguments can be positive or negative, so the ‘int’ declaration is required in this case. The sign of the speed input argument is converted to the appropriate direction flag value and a negative input speed is converted to a positive value for the SetLeftMotorDirAndSpeed() call.
RunBothMotorsMsec(bool bisFwd, int timeMsec, int gl_Leftspeednum, int gl_Rightspeednum)
All this function does is call RunBothMotors(), then delay for the requested amount of time, then stop the motors. Note that RunBothMotors() does not check the speed arguments for range or sign.
MoveReverse(int gl_Leftspeednum, int gl_Rightspeednum):
MoveReverse() is used extensively in ‘CheckForUserInput()’, but only twice elsewhere ( both times in IRHomeToChgStn()).
MoveAhead(int gl_Leftspeednum, int gl_Rightspeednum):
Similar to MoveReverse(), but used more outside ‘CheckForUserInput()’. Once in ExecuteRearObstacleRecovery(), once in TrackLeftWallOffset(), once in TrackRightWallOffset(), once in IRHomeToChgStnNoPings(), once in IRHomeToChgStnNoPingsPID(), twice in IRHomeToChgStn().
int gl_Leftspeednum, int gl_Rightspeednum:
These symbols are everywhere in the code, in a global variable declaration, in the signature of many of the motor functions, and in the code itself as local variables in the functions that have those symbols in the signature.
As an experiment I commented the global uint16_t definitions out and re-compiled. I got a bunch of ‘was not declared in this scope’ errors, but they were all like the following snippit:
1 2 3 4 5 6 7 8 9 10 11 |
//04/05/22 have to use local var here, as result could be negative int16_t leftSpdnum = MOTOR_SPEED_QTR + WallTrackOutput; int16_t rightSpdnum = MOTOR_SPEED_QTR - WallTrackOutput; //04/05/22 Left/rightSpdnum can be negative here - watch out! rightSpdnum = (rightSpdnum <= MOTOR_SPEED_HALF) ? rightSpdnum : MOTOR_SPEED_HALF; //result can still be neg gl_Rightspeednum = (rightSpdnum > 0) ? rightSpdnum : 0; //result here must be positive leftSpdnum = (leftSpdnum <= MOTOR_SPEED_HALF) ? leftSpdnum : MOTOR_SPEED_HALF;//result can still be neg gl_Leftspeednum = (leftSpdnum > 0) ? leftSpdnum : 0; //result here must be positive MoveAhead(gl_Leftspeednum, gl_Rightspeednum); |
in the above code a local int16_t variable is declared because the result could be negative. Then the local variables are constrained into the range (0-255) and then loaded into the gl_Left/Rightspeednum global vars, and also passed to MoveAhead(). This only occurs in the two TrackLeft/RightWallOffset() functions.
gl_Left/Rightspeednum global vars are also used in the ‘OutputTelemetryLine()’ function
So it looks like the usage in the above snippet is actually OK. The global vars wind up being loaded with the latest left/right speed values just before those values are sent to the motor driver. The usage in the telemetry output functions are also OK, as they just print the current left/right speed value
gl_Left/Rightspeednum used in function declarations:
I re-educated myself on the fact that formal function declarations don’t actually need parameter names – just the type declarations, so:
1 |
void RunBothMotorsMsec(bool bisFwd, int timeMsec = 500, int gl_Leftspeednum = MOTOR_SPEED_HALF, int gl_Rightspeednum = MOTOR_SPEED_HALF); |
could just as easily be written:
1 |
void RunBothMotorsMsec(bool, int = 500, int = MOTOR_SPEED_HALF, int = MOTOR_SPEED_HALF); |
so maybe my use of the gl_Left/Rightspeednum names for these parameters wasn’t quite so scary bad as I thought. Still, defining the same symbol name in two different contexts as two different types (uint16_t and int) is demonstrably a bad idea, even if one of the symbol usages is ignored by the compiler (after all, this usage is what resulted in my current freakout). I changed these to ‘uint16_t leftspeednum’ and ‘uint16_t rightspeednum, in both the formal declaration at the top of the program (reqd for default parameter declaration) and the ‘inline’ declaration.
I wound up changing the following lines:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
//void RunBothMotorsMsec(bool bisFwd, int timeMsec = 500, int gl_Leftspeednum = MOTOR_SPEED_HALF, int gl_Rightspeednum = MOTOR_SPEED_HALF); void RunBothMotorsMsec(bool bisFwd, int timeMsec = 500, uint16_t leftspeednum = MOTOR_SPEED_HALF, uint16_t rightspeednum = MOTOR_SPEED_HALF); //void RunBothMotorsMsec(bool bisFwd, int timeMsec, int gl_Leftspeednum, int gl_Rightspeednum) void RunBothMotorsMsec(bool bisFwd, int timeMsec, uint16_t leftspeednum, uint16_t rightspeednum) //RunBothMotors(bisFwd, gl_Leftspeednum, gl_Rightspeednum); RunBothMotors(bisFwd, leftspeednum, rightspeednum); //01/06/24 chg int gl_Leftspeednum, int gl_Rightspeednum to uint16_t leftspeednum, uint16_t rightspeednum //void MoveReverse(int gl_Leftspeednum, int gl_Rightspeednum) void MoveReverse(uint16_t leftspeednum, uint16_t rightspeednum) //01/06/24 chg int gl_Leftspeednum, int gl_Rightspeednum to uint16_t leftspeednum, uint16_t rightspeednum //SetLeftMotorDirAndSpeed(REV_DIR, gl_Leftspeednum); //SetRightMotorDirAndSpeed(REV_DIR, gl_Rightspeednum); SetLeftMotorDirAndSpeed(REV_DIR, leftspeednum); SetRightMotorDirAndSpeed(REV_DIR, rightspeednum); //01/06/24 chg int gl_Leftspeednum, int gl_Rightspeednum to uint16_t leftspeednum, uint16_t rightspeednum //void MoveAhead(int gl_Leftspeednum, int gl_Rightspeednum) void MoveAhead(uint16_t leftspeednum, uint16_t rightspeednum) //01/06/24 chg gl_Leftspeednum, gl_Rightspeednum to leftspeednum, rightspeednum //SetLeftMotorDirAndSpeed(true, gl_Leftspeednum); //SetRightMotorDirAndSpeed(true, gl_Rightspeednum); SetLeftMotorDirAndSpeed(true, leftspeednum); SetRightMotorDirAndSpeed(true, rightspeednum); //01/06/24 chg int gl_Leftspeednum, int gl_Rightspeednum to uint16_t leftspeednum, uint16_t rightspeednum //void RunBothMotors(bool bisFwd, int gl_Leftspeednum, int gl_Rightspeednum) void RunBothMotors(bool bisFwd, uint16_t leftspeednum, uint16_t rightspeednum) //01/06/24 chg gl_Leftspeednum, gl_Rightspeednum to leftspeednum, rightspeednum //SetLeftMotorDirAndSpeed(bisFwd, gl_Leftspeednum); //SetRightMotorDirAndSpeed(bisFwd, gl_Rightspeednum); SetLeftMotorDirAndSpeed(bisFwd, leftspeednum); SetRightMotorDirAndSpeed(bisFwd, rightspeednum); |
In addition, there are a number of places where the output from the PIDCalcs() function is added to or subtracted from the current speed to produce the next speed value, but the initial adjustment is to a ‘uint16_t’ variable. This is problematic because the initial adjustment can result in a negative value being loaded into a uint16_t variable, with unexpected (if still well-defined) behavior. The fix for this is to change the type of the ‘local’ variable to ‘int’ vs ‘uint16_t’ to accommodate the potential for negative values, and only load the result into the global ‘uint16_t’ variable when it is certain the result is positive. This resulted in the following changes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
TrackLeftWallOffset: //01/06/24 chg type from uint16_t to int to prevent unexpected behavior if result is negative int leftSpdnum = MOTOR_SPEED_QTR + WallTrackOutput; int rightSpdnum = MOTOR_SPEED_QTR - WallTrackOutput; //04/05/22 Left/rightSpdnum can be negative here - watch out! rightSpdnum = (rightSpdnum <= MOTOR_SPEED_HALF) ? rightSpdnum : MOTOR_SPEED_HALF; //result can still be neg gl_Rightspeednum = (rightSpdnum > 0) ? rightSpdnum : 0; //result here must be positive leftSpdnum = (leftSpdnum <= MOTOR_SPEED_HALF) ? leftSpdnum : MOTOR_SPEED_HALF;//result can still be neg gl_Leftspeednum = (leftSpdnum > 0) ? leftSpdnum : 0; //result here must be positive TrackRightWallOffset: //06/01/24 chg type to 'int' vs 'uint16_t' to prevent unexpected behavior with negative values //int16_t leftSpdnum = MOTOR_SPEED_QTR - WallTrackOutput; //int16_t rightSpdnum = MOTOR_SPEED_QTR + WallTrackOutput; int leftSpdnum = MOTOR_SPEED_QTR - WallTrackOutput; int rightSpdnum = MOTOR_SPEED_QTR + WallTrackOutput; IRHomeToChgStnNoPings(): //06/01/24 chg to local 'int' var to prevent unexpected behavior with negative values //gl_Leftspeednum = initleftspeed + IRHomingOutput; //gl_Rightspeednum = initrightspeed - IRHomingOutput; int leftspeednum = initleftspeed + IRHomingOutput; int rightspeednum = initrightspeed - IRHomingOutput; //gl_pSerPort->printf("gl_Left/Rightspeednum = %d / %d\n", gl_Leftspeednum, gl_Rightspeednum); //limit wheel speeds to valid range (0-255) //gl_Leftspeednum = (gl_Leftspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : gl_Leftspeednum; //gl_Leftspeednum = (gl_Leftspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : gl_Leftspeednum; //gl_Rightspeednum = (gl_Rightspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : gl_Rightspeednum; //gl_Rightspeednum = (gl_Rightspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : gl_Rightspeednum; gl_Leftspeednum = (leftspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : leftspeednum; gl_Leftspeednum = (leftspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : leftspeednum; gl_Rightspeednum = (rightspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : rightspeednum; gl_Rightspeednum = (rightspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : rightspeednum; //DEBUG!! gl_pSerPort->printf("%lu\t%2.2f\t%lu\t%lu\t%2.2f\t%2.2f\t\t%d\t%d\n", millis(), GetBattVoltage(), IRFinalValue1, IRFinalValue2, IRHomingl_RSteeringVal, IRHomingOutput, gl_Leftspeednum, gl_Rightspeednum); //UpdateRearLEDPanelForHoming(gl_Leftspeednum, gl_Rightspeednum); UpdateRearLEDPanelForHoming(IRHomingl_RSteeringVal); MoveAhead(gl_Leftspeednum, gl_Rightspeednum); IRHomeToChgStnNoPingsPID(): //06/01/24 chg to local 'int' var to prevent unexpected behavior with negative values //gl_Leftspeednum = initleftspeed + IRHomingOutput; //gl_Rightspeednum = initrightspeed - IRHomingOutput; int leftspeednum = initleftspeed + IRHomingOutput; int rightspeednum = initrightspeed - IRHomingOutput; //gl_pSerPort->printf("gl_Left/Rightspeednum = %d / %d\n", gl_Leftspeednum, gl_Rightspeednum); //limit wheel speeds to valid range (0-255) //gl_Leftspeednum = (gl_Leftspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : gl_Leftspeednum; //gl_Leftspeednum = (gl_Leftspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : gl_Leftspeednum; //gl_Rightspeednum = (gl_Rightspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : gl_Rightspeednum; //gl_Rightspeednum = (gl_Rightspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : gl_Rightspeednum; gl_Leftspeednum = (leftspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : leftspeednum; gl_Leftspeednum = (leftspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : leftspeednum; gl_Rightspeednum = (rightspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : rightspeednum; gl_Rightspeednum = (rightspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : rightspeednum; //DEBUG!! gl_pSerPort->printf("%lu\t%2.2f\t%lu\t%lu\t%2.2f\t%2.2f\t\t%d\t%d\n", millis(), GetBattVoltage(), IRFinalValue1, IRFinalValue2, IRHomingl_RSteeringVal, IRHomingOutput, gl_Leftspeednum, gl_Rightspeednum); //UpdateRearLEDPanelForHoming(gl_Leftspeednum, gl_Rightspeednum); UpdateRearLEDPanelForHoming(IRHomingl_RSteeringVal); MoveReverse(gl_Leftspeednum, gl_Rightspeednum); IRHomeToChgStn(): //06/01/24 chg to local 'int' var to prevent unexpected behavior with negative values //gl_Leftspeednum = initleftspeed + IRHomingOutput; //gl_Rightspeednum = initrightspeed - IRHomingOutput; int leftspeednum = initleftspeed + IRHomingOutput; int rightspeednum = initrightspeed - IRHomingOutput; //gl_pSerPort->printf("gl_Left/Rightspeednum = %d / %d\n", gl_Leftspeednum, gl_Rightspeednum); //limit wheel speeds to valid range (0-255) //gl_Leftspeednum = (gl_Leftspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : gl_Leftspeednum; //gl_Leftspeednum = (gl_Leftspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : gl_Leftspeednum; //gl_Rightspeednum = (gl_Rightspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : gl_Rightspeednum; //gl_Rightspeednum = (gl_Rightspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : gl_Rightspeednum; gl_Leftspeednum = (leftspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : leftspeednum; gl_Leftspeednum = (leftspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : leftspeednum; gl_Rightspeednum = (rightspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : rightspeednum; gl_Rightspeednum = (rightspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : rightspeednum; //DEBUG!! gl_pSerPort->printf("%lu\t%2.2f\t%lu\t%lu\t%2.2f\t%2.2f\t\t%d\t%d\n", millis(), GetBattVoltage(), IRFinalValue1, IRFinalValue2, IRHomingl_RSteeringVal, IRHomingOutput, gl_Leftspeednum, gl_Rightspeednum); //UpdateRearLEDPanelForHoming(gl_Leftspeednum, gl_Rightspeednum); UpdateRearLEDPanelForHoming(IRHomingl_RSteeringVal); MoveAhead(gl_Leftspeednum, gl_Rightspeednum); //06/01/24 chg to local 'int' var to prevent unexpected behavior with negative values //gl_Leftspeednum = initleftspeed + IRHomingOutput; //gl_Rightspeednum = initrightspeed - IRHomingOutput; int leftspeednum = initleftspeed + IRHomingOutput; int rightspeednum = initrightspeed - IRHomingOutput; //gl_pSerPort->printf("gl_Left/Rightspeednum = %d / %d\n", gl_Leftspeednum, gl_Rightspeednum); //limit wheel speeds to valid range (0-255) //gl_Leftspeednum = (gl_Leftspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : gl_Leftspeednum; //gl_Leftspeednum = (gl_Leftspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : gl_Leftspeednum; //gl_Rightspeednum = (gl_Rightspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : gl_Rightspeednum; //gl_Rightspeednum = (gl_Rightspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : gl_Rightspeednum; gl_Leftspeednum = (leftspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : leftspeednum; gl_Leftspeednum = (leftspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : leftspeednum; gl_Rightspeednum = (rightspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : rightspeednum; gl_Rightspeednum = (rightspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : rightspeednum; //DEBUG!! gl_pSerPort->printf("%lu\t%2.2f\t%lu\t%lu\t%2.2f\t%2.2f\t\t%d\t%d\n", millis(), GetBattVoltage(), IRFinalValue1, IRFinalValue2, IRHomingl_RSteeringVal, IRHomingOutput, gl_Leftspeednum, gl_Rightspeednum); //UpdateRearLEDPanelForHoming(gl_Leftspeednum, gl_Rightspeednum); UpdateRearLEDPanelForHoming(IRHomingl_RSteeringVal); MoveReverse(gl_Leftspeednum, gl_Rightspeednum); //06/01/24 chg to local 'int' var to prevent unexpected behavior with negative values //gl_Leftspeednum = initleftspeed + IRHomingOutput; //gl_Rightspeednum = initrightspeed - IRHomingOutput; int leftspeednum = initleftspeed + IRHomingOutput; int rightspeednum = initrightspeed - IRHomingOutput; //gl_pSerPort->printf("gl_Left/Rightspeednum = %d / %d\n", gl_Leftspeednum, gl_Rightspeednum); //limit wheel speeds to valid range (0-255) //gl_Leftspeednum = (gl_Leftspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : gl_Leftspeednum; //gl_Leftspeednum = (gl_Leftspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : gl_Leftspeednum; //gl_Rightspeednum = (gl_Rightspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : gl_Rightspeednum; //gl_Rightspeednum = (gl_Rightspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : gl_Rightspeednum; gl_Leftspeednum = (leftspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : leftspeednum; gl_Leftspeednum = (leftspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : leftspeednum; gl_Rightspeednum = (rightspeednum > MOTOR_SPEED_FULL) ? MOTOR_SPEED_FULL : rightspeednum; gl_Rightspeednum = (rightspeednum < MOTOR_SPEED_OFF) ? MOTOR_SPEED_OFF : rightspeednum; //DEBUG!! gl_pSerPort->printf("%lu\t%2.2f\t%lu\t%lu\t%2.2f\t%2.2f\t\t%d\t%d\n", millis(), GetBattVoltage(), IRFinalValue1, IRFinalValue2, IRHomingl_RSteeringVal, IRHomingOutput, gl_Leftspeednum, gl_Rightspeednum); //UpdateRearLEDPanelForHoming(gl_Leftspeednum, gl_Rightspeednum); UpdateRearLEDPanelForHoming(IRHomingl_RSteeringVal); MoveAhead(gl_Leftspeednum, gl_Rightspeednum); |
After all these edits, the program still compiles cleanly. As to whether or not it behaves cleanly, that is still a very open questions. Only time will tell!
Stay tuned,
Frank