我正在研究一些机器人运动学代码,我首先编写了用于计算关节角度的天真的,有意识的非优化函数,这样我就可以用逻辑分析仪测量时序并有一种切实的方法来测量增益在定点数学等优化中。
我有两个微控制器板,我正在玩:Teensy 2.0和Teensy 3.0。我正在使用Arduino环境为它们构建代码。与大多数Arduinos一样,2.0是8位16MHz AVR。 3.0是一个32位48MHz ARM皮质M4。
代码将引脚拉低,执行一条腿的IK计算,然后将引脚拉回高位。我正在使用一个古老的逻辑分析仪来测量线路的低时间。
奇怪的是,ARM板的边缘间隔时间明显延长! AVR在960us左右完成,但ARM需要更多像18.5ms!
这并不是我的想法。有没有人知道为什么会这样?
这是我正在使用的代码。不要介意这是故意非优化的事实,可能我在数学上不好,但这不是问题所在:)
#include <math.h>
#define lc 21.0
#define lf 40.0
#define lt 62.0
#define lfsqrd 1600.0
#define ltsqrd 3844.0
struct Vector {
double x;
double y;
double z;
};
struct Joints {
double c;
double f;
double t;
};
void calc_joints(struct Vector *foot, struct Joints *joints) {
double l1 = sqrt(pow(foot->y,2) + pow(foot->x, 2));
double l2 = l1 - lc;
double l3 = sqrt(pow(foot->z,2) + pow(l2, 2));
double tx = atan2(l2, foot->z);
double ty = acos( (pow(l3,2) + lfsqrd - ltsqrd) / (2 * l3 * lf) );
// todo: convert these from radians to degrees
joints->c = atan2(foot->y, foot->x);
joints->f = tx + ty;
joints->t = acos( (lfsqrd + ltsqrd - pow(l3,2)) / (2 * lf * lt) );
}
void setup() {
Serial.begin(9600);
pinMode(0, OUTPUT);
digitalWrite(0, HIGH);
}
void loop() {
digitalWrite(0, LOW);
struct Vector v = { 10, 20, 30 };
struct Joints j;
calc_joints(&v, &j);
digitalWrite(0, HIGH);
Serial.print(j.c);
Serial.print(", ");
Serial.print(j.f);
Serial.print(", ");
Serial.println(j.t);
}
答案 0 :(得分:3)
ARM cortex M4
Cortex M4中的FPU仅支持单精度,但您在代码中使用了大量 double 。这意味着软件计算而不是硬件。您是否尝试将double
变量和函数调用更改为float
?
答案 1 :(得分:0)
好奇的问题!请尝试以下代码作为检查时钟速度的快速方法:
boolean pinValue;
void setup() {
Serial.begin(9600);
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
pinValue = true;
}
void loop() {
pinValue = !pinValue;
digitalWrite(13, pinValue);
}
你的逻辑分析仪应该尽可能快地显示Arduino大约50%的占空比#34;用这个来确认您的电路板正在按照您的想法进行计时。
这将帮助您确定您的Teensy 3.0是否因为执行基本指令的时间而变慢,或者执行数学函数的指令在某种程度上对于ARM来说不是最优于AVR。如果它对于这个简单的程序来说速度较慢,我会强烈怀疑你没有像你想象的那样计时。
我建议你确认你的探针是按照你认为的方式接线的......即是&#34;慢&#34;频道真正连接到&#34;快速&#34;板?