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