JoergS5 parallel five bar scara
@bondus If you give me the code when tested, I can login into github (or I give you access rights, but then I need your account name). Sorry if I made errors in the program.
I bet it worked for you. Your plans are quite ambitious wanting to handle all working modes.
I tracked down the odd selection of arm-angles to getTheta(). I think the logic in there is a bit too simple to handle all cases of work modes, locations of actuators and limitation of angles. It would takes some brain-time with pen and paper to figure out a good logic for that. I made it work for my be changing the range of getAbsoluteAngle() from 0 - 360 to -90 - 270.
It's fascinating to see the arms air-printing at 240mm/s, with just 600mA to the steppers. Too bad I have no z-axis yet.
@bondus One paper which was useful to understand the work modes was called "DEVELOPMENT OF A FIVE-BAR PARALLEL ROBOT WITH LARGE WORKSPACE", one link to it is https://www.semanticscholar.org/paper/DEVELOPMENT-OF-A-FIVE-BAR-PARALLEL-ROBOT-WITH-LARGE-Campos-Bourbonnais/4f945b3db879c18c8fdf2b01860d8a9b2f9a274d
I wanted to restrict print area to a safe area, because printing outside will have other problems like lower resolution, variable speeds, instability of the mechanics. Crossing singularity to change work modes is an interesting task, however, e.g how Morgan tries it. I think it uses momentum to cross.
@bondus Thank you for sharing the video. I started to analyze movements with a wacom tablet, this could be interesting for you also. I want to use it to analyze precision of movements, ringing/vibrations and how stable the scara arms are in respect of Z direction (the pressure of the wacom pen).
@JoergS5, the DexTAR, I'll read that paper.
I think swapping from work mode 1 to work mode 2, and back, should be fairly easy, you do not have to use momentum to get through the singularity. Same thing swapping from 1 to 3, assuming your proximal arms can pass through the center. Swapping from 2 to 3 would have the distal arms "dangling" and you must use momentum to get past in a predictable way.
But the worst problem is probably to solve the motion planning in a good way. To know when it's a good idea swap. For 3D printing the only way I can see it being used is if you print multiple parts and swap mode between the different parts to reach different areas.
Using a tablet to track movement is a good idea.
I ordered some accelerometers/gyro modules yesterday. If I can get them to sample fast enough they should be good for measure ringing and vibrations, but not for positioning.
This little arm is ridiculous. I can easily push it to 800mm/s without skipping steps. It starts dancing around on my desk, it's just attached to a small piece of alu extrusion, the whole thing weighs less than 2kg.
@bondus Gyro and accelerators is a really good idea!
@JoergS5 , Another little issue found, and solved.
getQuadrant() must take x and y as float, not int.
There were some corner cases where the rounding of the float to an int placed the coordinate in the wrong quadrant. Leading to a small error in the inverse transform. Once it popped over into the right quadrant the error went away.
This could be seen when moving over such a border, the motors did a sudden move, just like they physically hit something.
I am tempted to create a test environment for the code. A dummy RRF where you plop in the FiveBarScaraKinematics.cpp as is and it runs a number of test and simulations to make sure the kinematics works as intended. It is a very complicated kinematics. A simple GUI with a virtual arm would be very cool too.
@bondus you are right with the getQuadrant() method. I will correct it, thank you.
The findings of you remind me that it would be better to use unit testing like I'm used from Java. I will try to install a testing framework to avoid those errors in the future.
@JoergS5, I got my prototype machine printing.
And it's creating some pretty nice prints.
I have struggled to accurately measure the angles of the arms at the endpoints. And if they are configured even a fraction of a degree wrong the resulting models are quite badly twisted. To make this kinematics more user friendly I think some kind of calibration method would be needed. It's much easier to measure a distance moved or the length of a printed part than to measure an angle. It could be as simple as to input the measured X and Y coordinates at the home position (relative to what was configured) and a tool computes the actual angles. Or as advanced as the klipper firmwares delta configuration, https://github.com/KevinOConnor/klipper/blob/master/docs/Delta_Calibrate.md.
Unfortunately a z-probe does not help for this problem.
Or I could have built my machine with better tolerances
And some live action: https://youtu.be/IxRO5NZx-u8
@bondus You have a nice printer and a good first result.
You are ahead of me, I am not finished building the printer yet. So my ideas to improve are theoretical:
- at the actuators, if you use gears, harmonic drives would be best, for zero backlash
- you can stabilize the arms by creating parallelograms between the hinges
- to measure the angles exactly, you can prolonge the arms. Additinally at the other side of the actuator (prolonge the arms to the other side)
- define reference points on the head bed and calibrate the hotend to those points
My current plan for the arms are CFK based crane-like arms: CFK has a good E-module, is light and has low (or even negative) heat expansion.
@bondus I rechecked your video, the only weakness I see is the left arm (left from the view of the actuators) where the arm can swing in vertical direction because it is only one, not two rods. Your construction with two ball bearings to stabilize vertically is very good IMHO.
I have struggled to accurately measure the angles of the arms at the endpoints. And if they are configured even a fraction of a degree wrong the resulting models are quite badly twisted. To make this kinematics more user friendly I think some kind of calibration method would be needed. It's much easier to measure a distance moved or the length of a printed part than to measure an angle.
I had a similar issue when calibrating my single-arm SCARA printer. For an outline of how I solved it, see the Calibration section at https://miscsolutions.wordpress.com/2017/08/27/converting-the-robotdigg-scara-printer-to-duet-electronics/#more-2563. Maybe it will give you some ideas.
@dc42, your "dab" idea is a good alternative to print a large calibration object. I just have to figure out a way to solve the equation. You had only two arms and one angle to adjust, we have four arms and two angles. A brute force numerical method should work fine assuming the initial values are reasonable. One more reason to make a dummy RRF to plug in the kinematics c++ file into.
@JoergS5, the main weakness of my arms are the rotational stiffness of the U-beams. When the elbow is at 90° the z-forces to the hotend are applied as rotation on the inner arm. When the arm is closest to the base the y-forces on the hotend tip are rotating the arms. When the arm is extended x-forces to the hotend tip are rotating the arms. I can see this by moving the arm around and checking by hand how stiff it is and seeing where it flexes.
If you do some mechanical simulations this should be very visible.
For the selection of arm material/geometry this is important. A CF rod with all fibres in one direction might not be good for this application.
I would love some harmonic drives. In my experience belted gears have pretty low backlash, but they are very limited in ratio. My current 1:6 gearing is too low (high?) for the size this arm turned out, it's almost down to 30 microsteps per mm at the bad areas. 1:30 or more would be a better gearing, the duet can run the steppers pretty fast.
I use normal deep groove bearings at the base, they are at a sufficient distance from each other to convert z forces at the hotend to horizontal forces. The thrust bearings, with grooved washers, in the elbows are not ideal for this use. They have to take some lateral forces which they are not designed for, but preloaded they keep things very stable, and the lateral loads are pretty low.
I should have put a large thrust bearing in the hotend joint too, there is one deep groove bearing there now. Cross roller bearings would be ideal in all joints, but $$$.
@JoergS5, we should join sources. I am updated to latest RRF, but with some features not working as they should (such as IsReachable()). I could setup a RRF fork on github. Ideally it would be linked back to your fork, my git skills are not that advanced.
wall of text
I see two weaknesses in today's code which I wish would be clarified before publishing in the official RRF code:
- the resolution of printing depends on the x-y coordinate. The should be a recommendation of a "good safe" print area. This needs to be tested
- the movement speed varies with x-y coordinates. RRF segments the movement into small parts, so this may not be a problem, but I am not sure about that. I want to measure it to be sure (e.g. measure whether the filament extrustion is even enough).
A final improvement would be to give instructions and help how to change work modes. A safe solution would be to add an additional actuator to cross the singularity areas.
@bondus For the hinges, I bought some ball bearings from POM material, to be light. But they have a lot of play. Another possibility is using Hylite, which is polypropylen and has low backlash and is light. One could produce the part from the plates https://www.display.3acomposites.com/hylite.html
You are right with CFK, one must use the correct ones, there are different ones with respect to fibre direction.
@JoergS5, I found one more little possible issue. I noticed one more "stepping function" issue when running the code on my PC, after some digging I found an abs() in getAbsoluteAngle(). According to the c standard abs using int. But it looks like that in RRF it actually resolves to using floats, odd. It's better to use a fabs() or fabsf(). I saw no difference in the prints.
Another issue is that when you try to do a CartesianToMotorSteps() of a coordinate that is physically unreachable by the arms (too far away) it does not complain. constraintsOk() does not catch that since the resulting angles and coordinates from getInverse() are NaN. I added a bunch of isnan() to getInverse() to never cache nan values, that works fine.
Hylite is a fascinating material. I guess you have seen http://zatsit.fr/, a hylite based delta printer. I backed the kickstarter.
I managed to "port" the kinematics to my PC with some careful copy-paste, and implemented a small command line utility to output a resolution drawing as an SVG (the easiest way to draw things) . It's fun to play around with arm lengths and limits and see where you end up. This is what my machine looks like:
@bondus abs is int, so it is casting the float to int and assigning to float, casting again. It is better to use fabs.
I found an alternative to harmonic drives: https://hackaday.com/2016/12/02/abacus-drive-is-a-speed-to-torque-game-changer/ and a 3D thing: https://www.youmagine.com/designs/abacus-drive-v0-v1 which may be useful
Your PC program is nice. The paper https://pdfs.semanticscholar.org/8a6f/7990e92b13ed7474a2f05b2ac6031193c227.pdf analyzes safe print areas, the deviations of serial vs. parallel scara and gives some hints about stabilizing the arms.
I changed my microstepping from 16 to 128 and now my machine prints really nice. It has pretty good repeatability. Using a dial gauge to measure X or Y I can see that it returns within +-25um after moving around. Not bad for a printed machine.
The main issue now is the wobbly Z. Even if it is light and moves fast it needs Z strength to push away imperfections from the lower layers. As it is now it uses imperfections as a kind of jump and they propagate up and along the layers. Producing waves on flat walls.
It's also pretty undamped. It keeps vibrating almost a second after a hit.
@JoergS5, running the kinematics on my PC and stretching it to the limits I can see that there are limitations and assumptions in the implementation. Inverse and forward transform do not always agree, and sometimes they returns very strange values.
It would be nice if it could handle the theoretical free robot with no limitations and no collisions of the arms. For all working modes.
I might go crazy on your code and make it behave in all corner cases...
@bondus Your results are really good, congratulations.
You have some minor problems with Z left and jumping. If your arms are hollow, you could fill them with sand. Filling only about 30-50 % to give them the possibility to move a bit to take up the energy. Fixing them in the arm direction (my first idea was small bags). This would stabilize Z movement and reduce vibrations. The cost is higher inertia and lower maximum speed, but I hope not much.
Your robot idea: there are robot constructions with parallel arms, where the Z axis is included. Kinematics is more complex, but maybe worth implementing. An example is the Dobot Magician *). I would implement the arm elements as trapezoid rods to get the overconstraint and stability of parallel elements.
*) Dobot Magician is visually what I mean, but the rods are fixed. I mean a construction where the rods have hinges each, similar to the parallel scara. This should result in higher resolution and less vibration.
I have done some thinking
There are 3 unpowered joints that causes a singularity when they are at 180 degrees, and at 0 (or 360) degrees. Below 180 is stable and over 180 is stable. It would make sense to define the work modes depending on those angles. An angle at 0-180 is one state, 180-360 another state. This would create 8 different modes with the 3 joints (2^3).
First we have the 4 modes that you named:
And then there are the 4 "inside out" modes. The same as 1-4, but on the other side of the machine.
I think that it we use these constraints in the code to pick the right solutions from the equations we will get a fairly simple solution, and it will be complete and general. Both forward and inverse transform should have only one solution in a given working mode, or my theories are wrong.
A few fun positions:
@JoergS5 , that wasn't too hard to implement . The code is a horrible mess and very inefficient, but it works. On my PC.
I skipped the extra 4 modes I came up with, they require the arm to travel through a singularity with the hotend joint at 180 degrees. Or even at 0 degrees! I think that is more or less impossible with a stepper driven arm.
And here is a new updated resolution map from my bot (assuming no collisions with anything and full 360 degree actuators). Green is mode 2, blue and red is mode 1 and 4. Yellow is mode 3.
I'll port it over to the Duet after a cleanup. I only have a Maestro board for the Scara, it has no FPU. So I have to be careful with all the floating point trigonometry. An obvious optimization is to not actually compute the angles of the joints, all we need to know is if it's a left turn or a right turn, that is easy to do without trigonometry.