Thermal spraying of a sphere (ball)

Hello everyone,
Since the beginning of this year we have an ABB IRB 4600 robot. The integrator has supplied a program with which we can perform about 80% of our thermal spraying work. For the other 20% (the specials), we make our own programs and the basic course was followed at ABB at the end of last year.
The problem we have now is to evenly coat a sphere. We have now created a program with the MoveC option.
The problem with this program is that the RPM remains the same and the robot speed is fixed.
What I am looking for is a program that can accelerate and slow down the speed of the robot in a circular motion.
The layer yield per pass is a maximum of 0.008 mm.
The sphere is sprayed in a rotating manner (around the y-axis).
The result is that the build-up of the sprayed layer close to the drive side is higher than the highest point of the sphere
Since the ball must be evenly coated over the entire surface (about 40 layers of 0.008 mm) I am looking for a possibility to vary the Speed of the robot (TCP) and the speed of the lathe at a (half) circle movement.
Who can help me to solve this problem?
The following (imperfect) code was created:
<code>
MODULE SprayWithoutRecipe
!Variable
LOCAL VAR NUM Diameter;
LOCAL VAR NUM StartPoint;
LOCAL VAR NUM SprayLenght;
LOCAL VAR NUM LinearSpeed;
LOCAL VAR NUM SprayDistance;
LOCAL VAR NUM TotalPasses;
LOCAL VAR NUM NrOfPasses;
LOCAL VAR NUM PassesDevide;
LOCAL VAR NUM LatheAcceleration;
LOCAL VAR NUM PassesUp;
LOCAL VAR robtarget rtLocal;
LOCAL VAR NUM RobotSpeed;
LOCAL VAR NUM nRobotSpeedNew;
LOCAL VAR NUM NewSprayDistance;
!Robot targets
LOCAL CONST robtarget rtDefaultStartPointHorizontal:=[[1443.00,-2227.85,439.93],[0.706979,-0.00777373,0.707033,0.0149554],[-1,-1,-1,0],[0,9E+09,9E+09,9E+09,9E+09,9E+09]];
!LOCAL CONST robtarget rtStartPointHorizontal:=[[1190.77,-1937.85,439.93],[0.706979,-0.00777373,0.707033,0.0149554],[-1,-1,-1,0],[0,9E+09,9E+09,9E+09,9E+09,9E+09]];
!LOCAL CONST robtarget rtEndPointHorizontal:=[[1190.77,-1627.85,439.93],[0.706979,-0.00777373,0.707033,0.0149554],[-1,-1,-1,0],[0,9E+09,9E+09,9E+09,9E+09,9E+09]];
!
LOCAL CONST robtarget rtCircleStart:=[[1143.00,-1934.00,657.00],[4.32071E-05,0.542363,-0.840144,-4.75697E-05],[-1,-1,-2,0],[0,9E+09,9E+09,9E+09,9E+09,9E+09]];
LOCAL CONST robtarget rtCircleMiddel:=[[721.50,-1447.00,657.00],[6.00717E-05,0.0065857,-0.999978,-1.54987E-05],[-1,-1,-1,0],[0,9E+09,9E+09,9E+09,9E+09,9E+09]];
LOCAL CONST robtarget rtCircleEnd:=[[1143.00,-1100.00,657.00],[0.00005,-0.51223,-0.85885,0.00002],[-1,-1,0,0],[0,9E+09,9E+09,9E+09,9E+09,9E+09]];
!
PROC rSprayPathWithoutRecipe()
Diameter:=UINumEntry(
\Header:="DIMENSIONS"
\Message:="What is the diameter in mm?"
\Icon:=iconInfo
\InitValue:=300
\MinValue:=10
\MaxValue:=1000
\AsInteger);
! Afstand
SprayDistance:=UINumEntry(
\Header:="DISTANCE"
\Message:="Spray distance in mm"
\Icon:=iconInfo
\InitValue:=250
\MinValue:=200
\MaxValue:=350
\AsInteger);
NrOfPasses:=UINumEntry(
\Header:="PASSAGES"
\Message:="Total number of passages"
\Icon:=iconInfo
\InitValue:=50
\MinValue:=1
\MaxValue:=100
\AsInteger);
!Calculate the speed and the spraying distance
nRobotSpeedNew:=(RobotSpeed/60)*1000;
NewSprayDistance:=((Diameter/2)+SprayDistance);
!Start
!Reset the counters
TotalPasses:=0;
!
MoveL Offs(rtStartPointHorizontal,-NewSprayDistance,-NewSprayDistance,0),v2500,fine,toolGPDJ2600\WObj:=wobjHorizontalAxis;
!
WHILE TotalPasses<NrOfPasses DO
!
!
MoveL Offs(rtCircleStart,-NewSprayDistance,-NewSprayDistance,0),v20,fine,tool0\WObj:=wobj0;
MoveC Offs(rtCircleMiddel,-NewSprayDistance,NewSprayDistance,0),Offs(rtCircleEnd,-NewSprayDistance,NewSprayDistance,0),v20,fine,tool0\WObj:=wobj0;
!
MoveL Offs(rtCircleEnd,-NewSprayDistance,NewSprayDistance,0),v20,fine,tool0\WObj:=wobj0;
MoveC Offs(rtCircleMiddel,-NewSprayDistance,NewSprayDistance,0),Offs(rtCircleStart,-NewSprayDistance,-NewSprayDistance,0),v20,fine,tool0\WObj:=wobj0;
!
!
TotalPasses:=TotalPasses+1;
ENDWHILE
!
!MoveL Offs(rtStartPointHorizontal,NewSprayDistance,StartPoint,580),v2500,fine,toolGPDJ2600\WObj:=wobjHorizontalAxis;
!
! Move to the idle position
MoveAbsJ jtIdle,v500,fine,tool0\WObj:=wobj0;
!
WaitRob\InPos;
ENDPROC
ENDMODULE
</code>
Comments
As I see it due to geometry of the sphere it is kind impossible to get an even distribution and the larger the percentage of the spheres surface you cover the more uneven the distribution will end up. Correct me if I'm wrong here.
If the sphere is rotated by an external axis how does the robot move?
As i understand you're doing a moveC from the top to the bottom of the sphere and then rotate the sphere one brush stroke with the external axis?
or do you hold the robot in more of a fixed position and rotate the external axis a full rotation and then step the robot down the width of the first "brush stroke"?
To give you an idee on the setup:
https://plasmaservice.nl/assets/uploads/Spraying_sphere.mp4
-------------------
288, 166, 0.995
266, 180, 1.078
244, 196, 1.175
220, 217, 1.303
200, 239, 1.433
For changing the speed of the robot arm while moving it, check out SpeedRefresh which overrides your current speed, although the manual states that "Note that with SpeedRefresh the speed override will not be done momentarily. Instead, there will be a lag of 0.3 - 0.5 seconds between the order and the influence on the physical robot."
To do that I would recommend using "TriggInt - Defines a position related interrupt" and send the speed to the lathe from there if you just gonna send a few commands. Then guess you would like to be able to set the acceleration as well to the average acceleration between two speed setpoints.
If you have the possibility to send speed changes frequently you could run a background task that monitors the position of the robot and calculates the radius of the sphere based on the momentary position of the robot and based on that calculates sends the appropriate rotational speed to the lathe.
60 x traverse rate = Step distance
RPM
@lemster68: Yes, I know the formula. We use that as well but only on fixed diameters like you mentioned.
How do i create a simi circle motion with more then 3 points? The manual is not clear on this. If this works, I will split the range up to 6 or even more points when posible.
MoveC pStart,p10,blah, blah blah
MoveC p10,p20, blah, blah, blah
MoveC p20,pMiddle, blah, blah blah
Do the same from the middle to the end point.