While we’ve fixed the behavior, I don’t understand why the behavior works this way:
The original:
motor.spin(vex::directionType::fwd, targety/3+(targetx-158)/3, vex::velocityUnits pct);
The fix:
motor.spin(vex::directionType::fwd, ((targety+(targetx-158))/3), vex::velocityUnits pct);
As far as I’m aware, both of them should behave exactly the same way, at least given no issues with really small numbers and types like int (eg. if targety and targetx are both int’s and targety is 2 while target x is 159, then the rounding gives different results). But in actuality, the targety/3 part seemed to be ignored in the original, while it was not ignored when grouping it with the targetx part via parentheses. Is there something I don’t know about commas and equations in C++?
Yes, that’s what I said in my original post. Small numbers like 2 and 159-158 will give odd results like that, but that’s not the issue. Things like targety being 70 result in 0 rotational speed in the first but not the second.
Unlike the RobotC’s Virtual Machine environment for Cortex, V5 runs the native code, which makes it vulnerable to all the issues common to unmanaged programming environments in the real world.
Where is “targety” variable declared? Could it be that its memory gets overwritten by something else?
I am not saying that it is a likely cause, but over the many years of programming, I’ve seen a couple of very bizarre cases where changing expression on line 100 in the code would affect results assigned in the line 95 even before the execution would get to the line 100!
What looked like totally impossible, turned out to be the side effect of optimizer reshuffling allocation of CPU registers for temporary values combined with our own bug that would overwrite memory location on the stack (executed from line 98), which was never noticed before, because the local variable intermediate value was kept in one of the CPU registers.
Then somebody changed expression in line 100, compiler optimizer pushed the local variable out of CPU register back to the stack and all the hell broke loose.
targety stores the y value from the largest object on the vision sensor. We had it printing out on the controller while having the robot elevated to watch the wheels spin. Putting the ball in the middle (targetx-158=0) would result in no wheels turning while printing out various expected targety values on the controller. Just by adding parentheses they motor behavior matched the values printed on the controller, at least as far as we could gauge visually. It seems truly bizarre to me, but really all we switched was the grouping with parentheses and got a drastic shift in behavior out of motor.spin while getting the same values on the controller. I’m at a complete loss to explain it.
@callen, could you move the print statements to be after the motor.spin() command?
Also, could you try to change the variable type from int to double?
There got to be some rational explanation of why this is happening.
Statistically, the most likely cause in such cases is a typo that everyone is overlooking (we could double check the full code if you want).
The next likely cause would be a more complex bug in some of your code, especially if you have multiple threads or utilize callbacks.
The next in line would be a bug in VexOS or supporting libraries code that causes stray memory overwrites.
And, finally, least likely but still possible is the bug in the compiler itself.
yes, there nearly always is.
for example, we know that the sdk in VCS still has a bug when using largestObject (fixed in the SDK included with VEXcode)
Not impossible, both VCS and VEXcode are using clang, not gcc, and we know of one really frustrating bug that I’ve never found a workaround for.