If atan2() returns a negative result, add 360 degrees (or the equivalent in radians) to the result.
Neil 2010/6/11 Viesturs Lācis <viesturs.la...@gmail.com> > 2010/6/11 Przemek Klosowski <przemek.klosow...@gmail.com>: > >> 1 #include "rtapi_math.h" > >> 2 #include "kinematics.h" /* these decls */ > >> 3 > >> 4 const double head_offset = 200; > >> 5 > >> 6 PmCartesian old; > >> 7 > >> 8 in t kinematicsForward(const double *joints, > >> 9 EmcPose * pos, > >> 10 const KINEMATICS_FORWARD_FLAGS * fflags, > >> 11 KINEMATICS_INVERSE_FLAGS * iflags) > >> 12 { > >> 13 double xy_tan = atan2(pos->tran.y - old.y,pos->tran.x - old.x); > >> 14 pos->tran.x = joints[0] - head_offset * sin(joints[5]); > >> 15 pos->tran.y = joints[2] + head_offset * sin(joints[4]); > >> 16 pos->tran.z = joints[3] + cos(joints[4]) * cos(joints[5]) * > head_offset; > >> 17 pos->a = asin(sin(joints[4]) / cos(xy_tan)); > >> 18 if xy_tan = 90 + (180 * i), where i is not 0, but is 1, 2, 3, etc > >> or -1, -2, -3, -4 etc > >> 19 then pos->a = asin(sin(joints[5]) / sin(xy_tan)); > >> > > OK, but what is 'i'? or are you saying that the test is for > > (xy_tan-90) being an integer multiple of 180? without understanding > > your geometry, this doesn't make immediate sense to me... > > > > If You recall trignometry from elementary school, tangent values (just > like for sin and cos functions) repeat every 180 degrees. For example > tangent of 45 degrees is 1. Just like it is for 225, 405 etc. General > way to write it is tan(45 + 180*i) = 1, where i is integer - 1, 2, 3, > 4, 5 etc. > Actually I seem to have made this bit more complicated as necessary - > for me xy_tan should be in range from 0 to 359 (including both of > these numbers), so instead of writing "90 + (180 * i)", I could have > said "90 or 270". > > By the way, how should I limit the xy_tan in the mentioned range from 0 to > 359? > > For example, for deltaX = 1, deltaY = -1 in Excel for atan2 function I > get value -45 degrees, while I would like it to be 315. This way each > position for xy_would be described with only one possible value > instead of several. Like in the given example, it can be -45 or +315 > etc. > > > > > because you whip the value of pos->a betweenthe values based on joints[5] > and > > joints[4]--normally I would expect the pos values to be continuous. > > > > Just to make sure that I understand You correctly - do You see the > probpos->a = asin(sin(joints[5]) / sin(xy_tan));lem in the fact that I > want to switch from this formula pos->a = asin(sin(joints[4]) / > cos(xy_tan)); to this formula pos->a = asin(sin(joints[5]) / > sin(xy_tan));? > > If this is the case, then how should I treat the situation that for > xy_tan values 90 and 270 the cos(xy_tan) = 0 and dividing by zero is > error. How to solve that? In those situations the nozzle will be > moving along Y axis and all the tilt should be "in joint[5]", joint[4] > should be in its zero point. So in this situation joint[4] = 0, but > pos->a must not be zero. The same situation is for xy_tan values 0 and > 180 - joint [5] should be in its zero point and all the tilt should be > "in joint[4]. > > Are there any suggestions? > > Just to remind - I am trying to implement kinematics, where cutting > head with A and B rotary axis (rotating around X and Y axis > respectively) are behaving as a cutting head with A and C rotary axis > (rotating around X and Z axis respectively) where A angle (amount of > the tilt of the head) is given in g-code, but C is calculated as a > tangent of the head movement, so that direction of tilt is ALWAYS > perpendicular to direction of movement. > > It seems to me that I have managed implementation of calculating the > tangent, and that the struggle is with transforming these A-C style > kinematics into A-B style cutting head. > > > 2010/6/11 yann jautard <brico...@free.fr>: > > > > > > Viesturs Lācis wrote: > >> > >> 1) What would correct syntax for line 18 and 19 look like? > >> > > could be something like : > > > > 18 for (int i=1; i< limit; i++){ > > 19 if (xy_tan == (90+(180*i)) || xy_tan == (90-(180*i))) > > 19 pos->a = asin(sin(joints[5]) / sin(xy_tan)); > > 20 } > > > > where limit is the maximal value I can take. > > this code is not optimised, because for large "limit" value, il will > > take a long time to iterate. But should work right for a limit value of > > 5 or 10. > > > > Thank You for the code!, I will try it. > > with best regards, > Viesturs > > > ------------------------------------------------------------------------------ > ThinkGeek and WIRED's GeekDad team up for the Ultimate > GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the > lucky parental unit. See the prize list and enter to win: > http://p.sf.net/sfu/thinkgeek-promo > _______________________________________________ > Emc-users mailing list > Emc-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/emc-users > -- http://www.pixpopuli.com ------------------------------------------------------------------------------ ThinkGeek and WIRED's GeekDad team up for the Ultimate GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the lucky parental unit. See the prize list and enter to win: http://p.sf.net/sfu/thinkgeek-promo _______________________________________________ Emc-users mailing list Emc-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/emc-users