views:

103

answers:

1

I am given coordinates of two points in 3-D viz. shoulder point and object point(to which I am supposed to reach). I am also given the length from my shoulder-to-elbow arm and the length of my forearm. I am trying to solve for the unknown position(the position of the joint elbow). I am using cosine rule to find out the elbow angle. Here is my code -

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

struct point {
     double x, y, z;
};

struct angles {
     double clock_wise;
     double counter_clock_wise;
};

double max(double a, double b) {
     return (a > b) ? a : b;
}
/*
 * Check if the combination can make a triangle by considering the fact that sum
 * of any two sides of a triangle is greater than the remaining side. The
 * overlapping condition of links is handled separately in main().
 */
int valid_triangle(struct point p0, double l0, struct point p1, double l1) {
     double dist = sqrt(pow((fabs(p1.z - p0.z)), 2) + pow((fabs(p1.y - p0.y)), 2) + pow((fabs(p1.x - p0.x)), 2));
     if((max(dist, l0) == dist) && max(dist, l1) == dist) {
          return (dist < (l0 + l1));
     }
     else if((max(dist, l0) == l0) && (max(l0, l1) == l0)) {
          return (l0 < (dist + l1));
     }
     else {
          return (l1 < (dist + l0));
     }
}
/* 
 * Cosine rule is used to find the elbow angle. Positive value indicates a
 * counter clockwise angle while negative value indicates a clockwise angle.
 * Since this problem has at max 2 solutions for any given position of P0 and
 * P1, I am returning a structure of angles which can be used to consider angles
 * from both direction viz. clockwise-negative and counter-clockwise-positive
 */
void return_config(struct point p0, double l0, struct point p1, double l1, struct angles *a) {
     double dist = sqrt(pow((fabs(p1.z - p0.z)), 2) + pow((fabs(p1.y - p0.y)), 2) + pow((fabs(p1.x - p0.x)), 2));
     double degrees = (double) acos((l0 * l0 + l1 * l1 - dist * dist) / (2 * l0 * l1)) * (180.0f / 3.1415f);
     a->clock_wise = -degrees;
     a->counter_clock_wise = degrees;
}
int main() {

     struct point p0, p1;
     struct angles a;
     p0.x = 15, p0.y = 4, p0.z = 0;
     p1.x = 20, p1.y = 4, p1.z = 0;
     double l0 = 5, l1 = 8;

     if(valid_triangle(p0, l0, p1, l1)) {
          printf("Three lengths can make a valid configuration \n");
          return_config(p0, l0, p1, l1, &a);
          printf("Angle of the elbow point (clockwise) = %lf, (counter clockwise) = %lf \n", a.clock_wise, a.counter_clock_wise);
     }
     else {
          double dist = sqrt(pow((fabs(p1.z - p0.z)), 2) + pow((fabs(p1.y - p0.y)), 2) + pow((fabs(p1.x - p0.x)), 2));

          if((dist <= (l0 + l1)) && (dist > l0)) {
               a.clock_wise = -180.0f;
               a.counter_clock_wise = 180.0f;
               printf("Angle of the elbow point (clockwise) = %lf, (counter clockwise) = %lf \n", a.clock_wise, a.counter_clock_wise);
          }
          else if((dist <= fabs(l0 - l1)) && (dist < l0)){
               a.clock_wise = -0.0f;
               a.counter_clock_wise = 0.0f;
               printf("Angle of the elbow point (clockwise) = %lf, (counter clockwise) = %lf \n", a.clock_wise, a.counter_clock_wise);
          }
          else
               printf("Given combination cannot make a valid configuration\n");
     }
     return 0;
}

However, this solution makes sense only in 2-D. Because clockwise and counter-clockwise are meaningless without an axis and direction of rotation. Returning only an angle is technically correct but it leaves a lot of work for the client of this function to use the result in meaningful way. How can I make the changes to get the axis and direction of rotation ? Also, I want to know how many possible solution could be there for this problem.

Please let me know your thoughts ! Any help is highly appreciated ...

+2  A: 

The basic problem is that you're solving (necessarily) the angle between the two arm parts on a plane, but the plane itself is unspecified. The solution will involve either constraining the plane itself or constraining the location of the elbow to some state like "the lowest possible position" (and the two of these will likely have identical solutions).

So, define the plane, and locate the three ends on that plane.

dash-tom-bang
dash-tom-bang, no other information except the two points and the lengths is given. I found a reference - http://www.eng.utah.edu/~cs5310/chapter5.pdftheta2 = 2 * atan(sqrt((pow(l0 + l1, 2) - (dist * dist)) / ((dist * dist) - pow(l0 - l1, 2))));phi = atan2(p1.y, p1.x);psi = atan2(l1 * sin(theta2), (l0 + l1 * cos(theta2)));theta1 = phi - psi;Thus, return_config will return theta2 as the "elbow angle" and theta1 as the angle with the axis of rotation. I should also return the direction of rotation. Please, can anyone comment if I am on the right track or not ?
Onkar Deshpande
Yeah you just need to provide the information that you don't have. In other words, pick something that seems reasonable and try it out. ;)
dash-tom-bang