LImit XY coordinate in Polar plane

Hello everybody.
I have a 2-axis motor module (like an XY table) that has a circular base, so its movement is limited in a circular physical plane.

Each axis has a potentiometer to monitor the position. The reading range is 200 ~ 800 through serial reading.

I convert this value to a Cartesian plane (-300 @ 300) on both axes.

I control both engines using 4 buttons. Each button pair controls one axis. Movement can only be up, or down, or left or right. One at a time, there are no diagnal movements (two axes active at the same time)

Using an image to illustrate an example:

GREEN DOT: Let's say the module is at position -290, 10

ORANGE DOT: If I press the DOWN button, I set the target to be the minimum point on the Y axis: -290, -300

PINK DOT: To try to limit the movement in a circular plane, I convert the target to polar coordinates, limiting the radius by 300. I reconvert to Cartesian again and result is -208,5; -215,6 At this time, the X axis is shifted. And this is correct. Due to using the ZERO center as a reference, the angle resulting from the conversion changes the position of the two axes..

But I would like a way to set the target on the BLUE DOT, -290, -76,9 Moving only the Y axis, not both. And keeping the target inside the circular plane.

How do I adjust the angle to obtain the desired position?

You need to first calculate if the target is outside your reach if it’s not then you are fine otherwise you need to adjust the target.

What you want to find is the intersection point between the path that you would take and the circle.

You have two points so can calculate the linear equation describing the line

The circle equation is also known as you know the radius

Using polar coordinates will make the maths easy - let me know if you need help.

Hi, @sandreble
Welcome to the forum.

Program wise it might be worth reading about the constrain function.

Tom... :grinning: :+1: :coffee: :australia:

This is exactly what I need. But I don't see an easy way to create this limit at the intersection of the circle and the line of movement.

At first I thought, create an array for each axis, and try to somehow create a table with the limit values ​​in each position... So, as an axis moves from ZERO to the extremes, the limit on the other hand it decreases...

I don't know if this would be the best solution

Hello, thank you Tom. I appreciate the help, but I believe my problem is not in the programming part yet.
I'm sorry if I posted in the wrong forum.
I believe my problem now is trigonometry. Maybe after arriving at some equation, this function can help me with something.

using your 2D cartesian plan, you have a circle centered in (0,0) with radius R and you have two points, the current position P(Xp,Yp) and the target position T(Xt, Yt)

You want to calculate if T is within the circle and if not the position of the point where the segment going from P to T intersects the circle.

It's easier to solve this problem using polar coordinates, as it simplifies the equations when dealing with circles.

  • Convert Points P(Xp, Yp) and T(Xt, Yt) to Polar Coordinates (I assume you know how to do this) and so you have P(Rp, θp) and T(Rt, θt) where Rx is the distance from the origin to x, and θx is the angle.

  • To determine if Point T is Inside the Circle it's easy:
    ➜ If Rt is less than or equal to the circle's radius R, point T is inside the circle and you don't need to do any modification on the target
    ➜ If Rt is greater than R (meaning point T is outside the circle), you'll need to find the intersection point I. (it also means Rt is not null so dividing by Rt is OK)

We know that the equation of a circle in polar coordinates is Radius = constant (in this case, Radius = R). To find the intersection points, set Rp equal to R and solve for θi:

Rt = R
θi = θt ± arccos(R/Rt)

Convert the calculated θi values back to Cartesian coordinates to get the I(Xi, Yi) coordinates of the intersection point I:

Xi = R * cos(θi)
Yi = R * sin(θi)

In my opinion, you may be over-thinking it.

Suggestion: each time a step is required, calculate the new coordinates before stepping the relevant motor. Then calculate the distance from the new coordinates to the centre using Pythagoras. If the distance exceeds 300, don't step the motor.

the point is outside the circle if the distance of the point from the origin, sqrt(x * x + y * y), is > radius of the circle

Simple and elegant. I don't need to calculate the target, distance, just do this check and if true, turn off the motor.
Thank you very much.

Thank you all for your help. PaulRB and especially J-M-L. I was already working on your tips, but gcjr proposed an easier alternative.

Sure if you

then all the maths are unnecessary.

the maths was really related to your initia ask

I assumed you had a GRBL type of language where you set targets in the commands you send to an engine

PS: @PaulRB 's suggestion

is what @gcjr wrote in a formula as sqrt(x2 + y2) is the distance

given you know the radius and it's fixed you should optimize the implementation and not take the square root and just compare x2 + y2 to R2 (a constant). It will be faster.

1 Like

Danger is: if you wait until the distance is >300, you may be too late to stop the motor before it moves off the base. Your code may need to estimate how much the motor will move before it next performs the check, so it can stop the motor before it moves off the base. This is pretty easy if you assume that your code reads the potentiometers more-or-less regularly. You just measure the change in readings since the previous readings, and assume it will move by the same amount again before the next reading.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.