Makeblock-official / mDrawBot

mDrawbot is a four-in-one drawing robotic kit, you can assembly into 4 different configuration drawing robots, learn more from Makeblock official website

Home Page:http://www.makeblock.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Bugs in driver software (buffer overflows and inaccurate positioning)

robbo1 opened this issue · comments

  1. There is no test for input exceeding the buffer, there should be a test on the buffer index to check that input characters received past the 64 byte limit do not get written to memory beyond the end of the input buffer.
  2. The drawings lose positional accuracy after drawing. The more drawing the more likely hood that the pen will not be accurate. This occurs because in the "doMove" function floating point arithmetic is used and the "stepA' & "stepB" variables often will be a fraction smaller than the real interval. Consequentially the for loop will often be one short of the completion of the move, which leaves the arms one step out from the recorded positions. I noted that someone had commented out the correct "for" statement and put another in that loops one too few.
    The loop correctly checks if the motors have moved the full distance or not, so for the times the extra loop is unneeded it will do nothing, but when it is needed then the motors move the full amount.
    I noticed the error when doing drawings (eg impossible box) and the overlapping lines would be some 3-5 mm out. After fixing the bug the lines overlap on top of each other correctly.
    The "for" loops limit test should be "i<=maxD".
  3. The calculations of "th1" & "th2" are overly complex and the use of the cosine law would simplify the maths removing the requirements for variables to the 4th power which reduces the accuracy of floating point calcs have a real limit on the number of significant digits. By only having variables squared the factors do not lose so many significant digits.
  4. No tests for the motors going out of range. That is exceeding the angles allowed and "crashing" into the framing. Tests should be in place for no-go zones resulting the pen being raised and no movement. With the correct tests then the issue of th1 & th2 calculations giving invalid values would not happen.
  5. I can make the changes for you if you wish as I have done embedded programming for decades now.

Thanks robbo1, you're good ! I hope they will hear your advice and make the modification. Thanks a lot

Hi robbo1,
Looks like you patched the code for points 2 and 3 already by in that description.
I think it will be great if you make a pull request with your code changes. That will help to fix it sooner it will go straight forward into merge.
I guess that all those bugs you mentioned apply to xyBot-scara, or also refer to other firmwares?
I had some issues with carRobot when sending "small" movements (10-15mm), that they are ignored and doesn't event try to move. Experienced such issues too?

Thanks

I did changes for point 2 at this stage. When I built the mscara and found the drawings were not drawing overlapping lines on top of each other (the box & car drawings) I decided to investigate further and code review the driver program. When I did that I saw that rookie mistake of thinking floating point calcs EXACTLY mirrored real floating point/fractions was in the code.

Namely in floating point libraries (any computer doing floating point really) , if you assign the variable "a" with "X divided by Y" then adding "a" "Y" times does not usually equal X, but rather some value a slightly bit less than X.

Thus by doing the loop one more time then "a" added "Y+1" times will be > X

Of course the real solution, if I was to "pull" and modify (which I don't know how to in GIT yet) the code I would not have a set number of loops but rather end the loop when no more tests are needed. This is because thinking about it more, it is possible certain movements that one more loop may not be enough. That would happen for very small X or Y moves when the other coordinate is large enough.

If I did modify the code for them, then I would implement all the above points and more.

One thing I will be experimenting with is to enable the second arm to go past 180 degrees so that it can draw in more areas. This would mean that it might be drawing with the arms the way they are now and when needed it recalculates the arm angles so that the 2nd arm bends the other way.

To do point 4 and the above idea, I OR makeblock would have to add options to the user to set the limits since the user may have modified the design and desire/need different angles.

Thank you @robbo1 , you are right about the floating points. It also confuse me why the "<=maxD" never works fine. The scara inverse kinetic is solved by matlab symbols, i run couple tests and there is no image part of the solution(have not do complete test on every points in the plane).
And feel free to push to the branch, we can also modify the GUI site to cooperate your code.

I am working on Grey Scale engraving at the moment and should be testing this week. After I do that I will make proper changes the driver and push it. Also will suggest changes to the GUI.

The for loop with "<=maxD" works correctly for all the drawings I tested. BUT the better way is to loop until both motors reach their target positions, rather than assume a loop count. This is because the very slight error in additions could theoretical require 2 or more extra loops.

@robbo1,
Thinking about the integer/ float computations, are you also considering moving all computations to integer values to avoid "round" effects? or that seems to be under control with the new control loops?

@robotiko,
No because the current method requires moving odd number of steps for each motor each minor movement. So it is still easier to use float, and use the basic method already in use. Just that the looping control is not set to a predefine loop count but rather loop until all steps have completed.
If I do a pull/push on the driver then I may look into something else, but no real need to though.

Hi @robbo1,
curious about your current solution and the initial comments you made.
Making the biggest draw possible, and repeating the same draw several times, lines an points overlap or are still off by several mms after the fixing?
Float computations will always give the same results and from logical perspective, errors might not be accumulated, however mechanically, without closed loopthey might accumulate in each iteration.

What are your real experiences?
thanks

I think you misunderstand how the floating point values are being used.

To move from point A to B, we might have motor A moving 30 steps and motor B moving 100 points.
So for every 3.3333 steps of motor B we want motor A to move one
Rather than trying to do that precisely we say that every step of motor B we add 0.3 to motor A position and when when motor A position reaches >= 1.0 we move A one step and subtract 1.0 from the position.
Thus we get B moving 4 and A moving 1, then B moves 3 A moves one and so on.
I agree that integers can be used, but in this case it really doesn't matter, as long as we loop until both motors reach their final positions never moving a motor if it reached its final position before the other did.

My real experiences is that initially the impossible Box would be a disaster lining up overlapping lines with the bottom lines the worse at 3-6 mm out of place. BUT after adding the extra loop to the for loop it is accurate and the lines draw on top of each other to within the pen width. There is a very small difference, but without checking the svg file completely the very small difference (<0.2mm) might be in the svg to start with.
I noticed that the conversion from bmp to svg is an approximation. Straight lines can be wider in the middle than the ends, even though the bmp file had one pixel wide straight line

Hi @robbo1, thank you for your improvement. If you need us to test, don't hesitate. How do we download your version ? Thanks a lot

I have been working on the laser and testing a type of grayscale to attempt to reproduce an engraved image from a picture. Not easy and so have not actually done any workable mods to the driver yet. The Laser is driven by PWN but should not, because it has a constant voltage power supply circuit and PWM stops it working properly. Rather there is a pwm input elsewhere on the laser control board that works well, but will require an extra lead into the control box and to the arduino.

Also I found another bug that annoyed me because I missed the obvious C pointers 101 error and was looking for something in arduino. Thats what happens when you use a new platform for the first time.

The bug is that the parameter value decoding in the driver would lose/corrupt one of the values if another parameter was within a certain range of values. EG X coord could be corrupted if Y coord was (for example) in the range 100-110mm.

The problem occurs because the strtok_r was being called one more time because the loop test was testing the pointer from the last parameter and in the loop strtok_r was called again which returns the null pointer but it is used as a valid pointer which sometimes under certain conditions looks like a valid string with a parameter in it.
That took me 2 days elapsed to track down, because I had real life things to do and while debugging I was looking for the bug elsewhere. And to make things worse a print statement made the code seem to work properly.
It was a rookie pointer error that I knew about in the days when UNIX was running on PDP-11s, but I overlooked it until today. Now I am testing out workable ways of grayscaling. It seems that I will have to do something similar to the old newspaper method of making the picture out of dots of various sizes.

Thanks a lot @robbo1 . It seems to be a little complex. Perhaps the project has been released too early. I hope the MakeBlock team are trying to correct the code too.

I have made a pull request that fixes the potential buffer overflows, positional inaccuracies due to code errors, and fixed a intermittent parameter value corruption that can cause wild movements of the arms

@robbo1 you're the best ! 👍

GREAT!! @robbo1.
Thanks a lot.

I have succeeded in engraving a picture on wood, but it requires an alternative way to connect the laser electronics to the controller. (one extra cable from the controller to an existing connector on the laser electronics board. Extra code in the driver is needed. At this stage the mods are not refined enough to release. To continue work for picture engraving I will need to duplicate the rig for testing purposes and honestly I don't have the funds/ability to do that, even though I wish to.

I am now updating the driver to have more efficient calculation of the angles and to determine the two possible angles for motor 1 and the corresponding angles for motor 2. This will open up 3 quadrants and some of the 4th for drawing if one wishes to mount scara in the middle of a board. But in any case it will open up all of quadrants 1 & 2 when mounted as per the instructions. Also arm 2 will be able to bend either side of arm 1. Also limits will be included to prevent the arms from contacting the mounting/frame.

It took a little time to ensure the maths was correct and that it would be possible to automatically choose which of the angles to use for motor 1. The new angle calc system plus existing code clean up is best done by a complete rewrite of those components in the driver.

I hope to provide a beta version of the code suitable for real life testing of the new calcs/stepping within 2 weeks.

My update addresses anything outstanding on this issue. Closing this issue