为什么这个程序不起作用?

时间:2012-08-28 03:51:29

标签: c for-loop robotics radians inverse-kinematics

//这是一个寻找机器人手臂运动学的程序。我的怀疑不在于:-)。我的程序执行但始终打印“位置无法处理”,即使对于已知值,它也是如此。在这里我使用弧度来表示角度,因为那是我理解的东西。请告诉我如何遇到这个,甚至告诉我更好的方法来实现它。谢谢。// 现在,这个编辑过的程序可以运行,但它的速度很慢..有人可以提出一种优化方法吗?

#include<stdio.h>
#include<math.h>
#include<conio.h>
int main()
{
    float a, b, c, d;
    int a1, b1, c1, d1;
    int x = 0, y = 0, z = 0;
    int x1 = 0, y1 = 0, z1 = 0;
    int i = 0, j = 0;
    printf("Enter X value: \n");
    scanf("%d", &x);
    printf("Enter Y value: \n");
    scanf("%d", &y);
    printf("Enter Z value: \n");
    scanf("%d", &z);
    for (a1 = -100 ; a1 <= 100 ; a1++)
    {
            printf("%d \t", j++);
            for (b1 = 0; b1 <= 180; b1++)
        {
            for (c1 = -100; c1 <= 100; c1++)
            {
                              for (d1 = -45; d1 <= 45; d1++)
                      {
                       a = a1 * 0.0174532925;
                       b = b1 * 0.0174532925;
                       c = c1 * 0.0174532925;
                       d = d1 * 0.0174532925;
                               x1 = (11*cos(d+c+b+a)+11*cos(d+c+b-a)+12*cos(c+b+a)+12*cos(c+b-a)+9*cos(b+a)+9*cos(b-a))/2;
                               if(x1 == x)
                               {
                                           y1 =(11*sin(d+c+b+a)-11*sin(d+c+b-a)+12*sin(c+b+a)-12*sin(c+b-a)+9*sin(b+a)-9*sin(b-a))/2;
                                           if(y1 == y)
                                           {
                                                 z1 = 11*sin(d+c+b) + 12*sin(c+b) + 9*sin(b);
                                                 if(z1 == z)
                                                 {
                              i = 1;
                              goto status;
                                                 }
                                            }
                                  }
                }
            }
        }
    }
    status:
    if(i == 0)
    printf("*****Positon unacheivable*****");
    else
        printf(" The joint angles for the desired positon are \n %d \t %d \t %d \t %d \n", a1, b1, c1, d1);
        getch();

}

3 个答案:

答案 0 :(得分:1)

首先阅读本文或第二篇,但请阅读: What Every Computer Scientist Should Know About Floating-Point Arithmetic

0.02在大多数计算机上无法准确表示。它将大致代表。在你的循环中,每次增加大约0.02时,你的舍入误差就会增大并增长。

答案 1 :(得分:0)

你要求速度优化:

你有

for (a...)
   for (b..)
      for (c...)
         for (d...)
            ...
            11*cos(d+c+b+a) + 9*cos(b+a) + 12*cos(c+b+a)
            ...

更好的是

for (a...)
   for (b..)
      mybpa = 9*cos(b+a)
      for (c...)
         mycpbpa = 12*cos(c+b+a)
         for (d...)
            mydpcpbpa = 11*cos(d+c+b+a)
            ...
            mydpcpbpa + mycpbpa + mybpa
            ...

你尽可能早地进行耗时的计算。您应该在达到该级别时计算所有这些值,以便它们在下一个循环中不再更改。 你甚至应该在不改变

的情况下尽快进行小计9*cos(b+a)+9*cos(b-a)

答案 2 :(得分:0)

这是一个简单的爬山算法。它以a = b = c = d = 0开始,测量到所需x,y,z的距离,然后对a,b,c,d进行小的随机调整,并保留改善距离的那些。

它将永远运行,除非在极少数情况下找到完全匹配;你可以选择停止状态。如果需要阻止它选择超出允许范围的a,b,c,d值,你也可以在随机性上设置一些界限,因为我太懒了,不能把它放进去。

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

static double getdist(double x, double y, double z,
                      double a, double b, double c, double d)
{
        double x1, y1, z1;

        x1 = (11*cos(d+c+b+a)+11*cos(d+c+b-a)+12*cos(c+b+a)+12*cos(c+b-a)+9*cos(b+a)+9*cos(b-a))/2;
        y1 = (11*sin(d+c+b+a)-11*sin(d+c+b-a)+12*sin(c+b+a)-12*sin(c+b-a)+9*sin(b+a)-9*sin(b-a))/2;
        z1 = 11*sin(d+c+b) + 12*sin(c+b) + 9*sin(b);

        return (x1-x)*(x1-x) + (y1-y)*(y1-y) + (z1-z)*(z1-z);
}

int main(int argc, char **argv)
{
    char *end;
    double x, y, z, a, b, c, d, dist, best;

    if(argc != 4) {
        fprintf(stderr, "Usage: %s x y z\n", argv[0]);
        return EXIT_FAILURE;
    }

    x = strtod(argv[1], &end);
    if(*end || !*argv[1]) {
        fprintf(stderr, "x value %s is not a number\n", argv[1]);
        return EXIT_FAILURE;
    }
    y = strtod(argv[2], &end);
    if(*end || !*argv[2]) {
        fprintf(stderr, "y value %s is not a number\n", argv[2]);
        return EXIT_FAILURE;
    }
    z = strtod(argv[3], &end);
    if(*end || !*argv[3]) {
        fprintf(stderr, "z value %s is not a number\n", argv[3]);
        return EXIT_FAILURE;
    }

    a = b = c = d = 0;
    best = getdist(x,y,z,a,b,c,d);
    printf("a=%f b=%f c=%f d=%f (dist=%f)\n", a, b, c, d, sqrt(best));
    srand(time(0));

    while(best) {
        double save_a, save_b, save_c, save_d;

        save_a = a;
        save_b = b;
        save_c = c;
        save_d = d;

        a += rand()*1./RAND_MAX*.02 - .01;
        b += rand()*1./RAND_MAX*.02 - .01;
        c += rand()*1./RAND_MAX*.02 - .01;
        d += rand()*1./RAND_MAX*.02 - .01;

        dist = getdist(x,y,z,a,b,c,d);

        if(dist < best) {
            best = dist;
            printf("a=%f b=%f c=%f d=%f (dist=%f)\n", a, b, c, d, sqrt(best));
        } else {
            a = save_a;
            b = save_b;
            c = save_c;
            d = save_d;
        }
    }
    return 0;
}