-1

//これは、ロボット アームの inv キネマティクスを見つけるためのプログラムです。私の疑いはありません:-)。私のプログラムは実行されますが、既知の値であっても常に「達成不可能な位置」を出力します。同じことを行います。ここでは、角度にラジアンを使用しました。これは c が理解するものだからです。これに遭遇する方法を教えてください。または、これを実装するためのより良い方法を教えてください。ありがとうございます。// さて、この編集されたプログラムは動作しますが、遅いです.. 誰かがこれを最適化する方法を提案できますか?

#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();

}

4

3 に答える 3

1

これを最初または 2 番目に読んでください。ただし、 すべてのコンピューター科学者が浮動小数点演算について知っておくべきこと

0.02 は、ほとんどのコンピューターで正確に表現できません。おおよその表現になります。ループでは、約 0.02 を追加するたびに、丸め誤差がどんどん大きくなります。

于 2012-08-28T04:48:15.557 に答える
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;
}
于 2012-08-28T07:08:22.840 に答える
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)は変わらないのですぐにやるべきです

于 2012-08-28T06:57:33.653 に答える