When the Rodrigues function is called with a rotation matrix as argument it provides 2 results.
I understand that the first item returned is the vector around which the rotation occurs and that the magnitude of the vector provides the angle of rotation. It seems that it provides a number (in radians) in the range (0,180) degrees for rotations covering (0,360) degrees, therefore there must be a way to determine the sign of the rotation. How do you do that.
As a supplimentary question, I understand that the second result is a Jacobian matrix. How do you use that?
The rotation is always positive, and when it "needs" to be negative (equivalently, closer to 360 than 0 degrees), the vector is simply flipped to the other side, so now it can be positive.
There is the "right hand rule". Right hand grabs vector, thumb pointing along the vector. Fingers indicate positive rotation around vector.
Example: Place your (right) fist on the desk, thumb up. Going +90 degrees is a quarter turn counterclockwise (inward). Going -90 degrees is a quarter turn clockwise (outward)... or +90 degrees with your thumb pointing into the desk.
The Jacobian is a bunch of derivatives, a vector in output-space for each component of the input. It tells you how stable the calculation is, i.e. how easily perturbed the result is, were any of the elements of your input vector to fluctuate by a bit.
Jacobians also show up in robotics. You can use them for inverse kinematics, combined with a solver. Given the Jacobian of your "robot arm", a tool center point, and a target, some math involving a Jacobian tells you what joints to move (a little bit) in which way to get closer to the target. The Jacobian depends on the current pose (i.e. it's not a constant matrix), so you'd recalculate it all the time.
Related
I was asked to find 5 equidistant points to a semi circle in python. So this is the code I wrote as that's what made sense to me mathematically
import math
r=float(input())/2
op=[[round(r*math.cos(i*math.pi/180),2),round(r*math.sin(i*math.pi/180),2)] for i in range(36,181,36)]
print(op)
But when I executed, my code failed the test cases as the answer the professor gave was based on the below code.
import math
r=float(input())/2
op=[[round(r*math.cos(i*math.pi/4),2),round(r*math.sin(i*math.pi/4),2)] for i in range(5)]
print(op)
What I can't seem to understand is why did he take range of 5 and how does i*pi/4 works?
Is the way I took my range(36,181,36) wrong? but it seems correct mathematically.
Below is the entire question for reference.(I haven't written the area finding part as I know how to code that its just this part of finding the coordinates that confuses me.)
A mobile phone network tower A covers the circular area which has the
diameter of D meters. Another mobile phone network tower B covers the
square shaped area with a side of D meters. The coverage area of
network tower B is overlapped on the network coverage area of tower A
in such a way that one side of square is perfectly fit with the
diameter of the circle through the direction of θ between 0 to π
radians. Write a Python function for returning the area of the shape
of the overlapped network coverage area. Also, the function should
return the five equally spaced co-ordinates (x, y) of the boundary of
the overlapped circle. Use for loop and nested list for the
calculation of co-ordinates. The output should be limited to two
decimal values.
Why pi/4...radian math? because we know that our semicircle is defined by a theta angle of 0-180 degrees or 0-pi. Since we need 5 points....and we start from 0....python counts 0,1,2,3,4. Therefore at MAX angle where i = 4 the calculated angle MUST be pi...therefore pi/4. Can be easily substituted for degree math if you like. math.cos and math.sin use radian math hence the use of pi/4 instead of 180/4.
Also your range is incorrect...as it does not satisfy the condition of 0-pi or 0-180 degrees
I have the coordinates of 6 points in an image
(170.01954650878906, 216.98866271972656)
(201.3812255859375, 109.42137145996094)
(115.70114135742188, 210.4272918701172)
(45.42426300048828, 97.89037322998047)
(167.0367889404297, 208.9329833984375)
(70.13690185546875, 140.90538024902344)
I have a point as center [89.2458, 121.0896]. I am trying to re-calculate the position of points in python using 4 rotation degree (from 0,90,-90,180) and 6 scaling factor (0.5,0.75,1,1.10,1.25,1.35,1.5).
My question is how can I rotate and scale the abovementioned points relative to the center point and get the new coordinates of those 6 points?
Your help is really appreciated.
Mathematics
A mathematical approach would be to represent this data as vectors from the center to the image-points, translate these vectors to the origin, apply the transformation and relocate them around the center point. Let's look at how this works in detail.
Representation as vectors
We can show these vectors in a grid, this will produce following image
This image provides a nice way to look at these points, so we can see our actions happening in a visual way. The center point is marked with a dot at the beginning of all the arrows, and the end of each arrow is the location of one of the points supplied in the question.
A vector can be seen as a list of the values of the coordinates of the point so
my_vector = [point[0], point[1]]
could be a representation for a vector in python, it just holds the coordinates of a point, so the format in the question could be used as is! Notice that I will use the position 0 for the x-coordinate and 1 for the y-coordinate throughout my answer.
I have only added this representation as a visual aid, we can look at any set of two points as being a vector, no calculation is needed, this is only a different way of looking at those points.
Translation to origin
The first calculations happen here. We need to translate all these vectors to the origin. We can very easily do this by subtracting the location of the center point from all the other points, for example (can be done in a simple loop):
point_origin_x = point[0] - center_point[0] # Xvalue point - Xvalue center
point_origin_y = point[1] - center_point[1] # Yvalue point - Yvalue center
The resulting points can now be rotated around the origin and scaled with respect to the origin. The new points (as vectors) look like this:
In this image, I deliberately left the scale untouched, so that it is clear that these are exactly the same vectors (arrows), in size and orientation, only shifted to be around (0, 0).
Why the origin
So why translate these points to the origin? Well, rotations and scaling actions are easy to do (mathematically) around the origin and not as easy around other points.
Also, from now on, I will only include the 1st, 2nd and 4th point in these images to save some space.
Scaling around the origin
A scaling operation is very easy around the origin. Just multiply the coordinates of the point with the factor of the scaling:
scaled_point_x = point[0] * scaling_factor
scaled_point_y = point[1] * scaling_factor
In a visual way, that looks like this (scaling all by 1.5):
Where the blue arrows are the original vectors and the red ones are the scaled vectors.
Rotating
Now for rotating. This is a little bit harder, because a rotation is most generally described by a matrix multiplication with this vector.
The matrix to multiply with is the following
(from wikipedia: Rotation Matrix)
So if V is the vector than we need to perform V_r = R(t) * V to get the rotated vector V_r. This rotation will always be counterclockwise! In order to rotate clockwise, we simply need to use R(-t).
Because only multiples of 90° are needed in the question, the matrix becomes a almost trivial. For a rotation of 90° counterclockwise, the matrix is:
Which is basically in code:
rotated_point_x = -point[1] # new x is negative of old y
rotated_point_y = point[0] # new y is old x
Again, this can be nicely shown in a visual way:
Where I have matched the colors of the vectors.
A rotation 90° clockwise will than be
rotated_counter_point_x = point[1] # x is old y
rotated_counter_point_y = -point[0] # y is negative of old x
A rotation of 180° will just be taking the negative coordinates or, you could just scale by a factor of -1, which is essentially the same.
As last point of these operations, might I add that you can scale and/or rotated as much as you want in a sequence to get the desired result.
Translating back to the center point
After the scaling actions and/or rotations the only thing left is te retranslate the vectors to the center point.
retranslated_point_x = new_point[0] + center_point_x
retranslated_point_y = new_point[1] + center_point_y
And all is done.
Just a recap
So to recap this long post:
Subtract the coordinates of the center point from the coordinates of the image-point
Scale by a factor with a simply multiplication of the coordinates
Use the idea of the matrix multiplication to think about the rotation (you can easily find these things on Google or Wikipedia).
Add the coordinates of the center point to the new coordinates of the image-point
I realize now that I could have just given this recap, but now there is at least some visual aid and a slight mathematical background in this post, which is also nice. I really believe that such problems should be looked at from a mathematical angle, the mathematical description can help a lot.
I'm scripting in python for starters.
Making this example simple, I have one edge, with uv Coordinates of ([0,0],[1,1]), so its a 45 degree angle. I have another edge that is ([0,0],[0,1]) so its angle is 0/360 degrees. My goal is to compare the angles of those two edges in order to get the difference so I can modify the angle of the second edge to match the angle of the first edge. Is there a way to do this via vector math?
Easiest to reconstruct and thus constructively remember is IMO the complex picture. To compute the angle from a=a.x+i*a.y to b=b.x+i*b.y rotate b back by multiplying with the conjugate of a to get an angle from the zero angle resp. the positive real axis,
arg((a.x-i*a.y)*(b.x+i*b.y))
=arg((a.x*b.x+a.y*b.y)+i*(a.x*b.y-a.y*b.x))
=atan2( a.x*b.y-a.y*b.x , a.x*b.x+a.y*b.y )
Note that screen coordinates use the opposite orientation to the Cartesian/complex plane, thus change use a sign switch as from atan2(y,x) to atan2(-y,x) to get an angle in the usual direction.
To produce a vector b rotated angle (in radians) w from a, multiply by cos(w)+i*sin(w) to obtain
b.x = cos(w)*a.x - sin(w)*a.y
b.y = cos(w)*a.y + sin(w)*a.x
You will have to rescale to get a specified length of b.
I have an issue that I can't seem to solve. I have already acquired data from another source and created 2 polynomials that are identical in shape but not in orientation, that is one is rotated x degrees compared to the other, and if you rotate the graph x degrees back they will match.
I have already taken the derivative of both of the graphs at a certain point.
I would like to graph these slopes onto a unit circle on a polar graph, and somehow find the angle difference between these two line segments of slope i and j that extend from the origin.
I'm fairly new to python so I so not know how to begin plotting these in polar or finding a way to determine the angle difference. I know that by hand, you can take the inverse tangent but that will only give you a range from +90 to -90. I would like my number to fall in the range from 0 to 360 for rotation.
Any help is appreciated. If this isn't enough info or if it isn't clear enough I can provide more.
This a draft of a 3D model I’m working with, and I would like to simulate its behaviour using python language. I have been researching on the best implementation for this simulation, but I found nothing that could fit real motion. I have tried analytical solving and failed because of uncertainity of certain parameters (certain errors for arm length) when those were measured.
I want to simulate the motion produced by a revolute joint and transfered to a system which is similar to the one depicted on the scheme.
At a certain time, the system might use the revolute joint and then turn to the following status.
Both status for the system are depicted on the next scheme.
An easy simplification with DH parameters would be:
The important thing is how to calculate the position and the angles of both non-controlled joints so that receptor joint angle (fixed point) can be calculated.
It is not only an inverse kinematics problem. It is necessary to consider the motion restrictions too. The motion must be determined by the revolute joint angle, the lenght of the links and the fixed point position and length.
The red circle in the next image depicts the possible positions for the second non-controlled point.
How would you simulate this motion?
There are one problematic position,
where intersections of two circles (described below)
has one point.
In this situation (we suppose it is planar situation (gravity is perpendicular
to all arm) and static situation) there isn't any force, which move with second non-controlled joint.
In dynamic we choose another solution for next step.
When intersection isn't exist,
that situation dosn't exist
and revolute joint cannot move
to this position.
We obtain (trivialy) motion restrictions when we calculate
all position and determine position where doesn't exist intersection.
Do you obtain end position of non-fixed point directly?
Older ansewer:
Simulate motion:
Calculate position of non controled points for all time between
start position and end position with step delta_t.
Draw step by step each calculated position (for example via Pygame).
Calculate:
First compute position of first non-controlled point (higher)
x_2 = x_1 + l_12 cos(Theta_1),
y_2 = y_1 + l_12 sin(Theta_2),
where X_1(x_1, y_1) is position of revolute point,
X_2(x_2, y_2) is position of first non-controlled point
and l_12 is length between X_1 and X_2
Compute intersection of two circle k_1 and k_2,
where k_1(first non-controlled point, l_23) and k_2(receptor joint, l_34),
where k(center of circle, radius of circle).
Step 2 has two solution.
We choose one of then.
To simulate motion, we must choose
"same solution".
Compute angle from two points:
alpha = math.atan2((y_2-y_1)/(x_2-x_1))