3

私はいくつかのロボット工学の運動学コードに取り組んでおり、ロジック アナライザーでタイミングを測定し、そのような最適化のゲインを測定する具体的な方法を持つことができるように、ジョイント角度を計算するための単純で意図的に最適化されていない関数を最初に書きました。固定小数点演算として。

Teensy 2.0 と Teensy 3.0 の 2 つのマイクロコントローラー ボードで遊んでいます。私は Arduino 環境を使用してそれらのコードを作成しています。2.0 は、ほとんどの Arduino と同様に、8 ビット 16MHz AVR です。3.0 は 32 ビット 48MHz ARM Cortex M4 です。

このコードは、ピンを Low に引き下げ、1 つの脚の IK 計算を実行してから、ピンを High に引き戻します。回線が低い時間を測定するために、古代のロジック アナライザーを使用しています。

奇妙なことは、ARM ボードのエッジ間の時間が大幅に長いことです。AVR は約 960us でそれを行いますが、ARM は 18.5ms ほどかかります!

これは私の心に合わない。なぜこれができるのかについての洞察を持っている人はいますか?

AVRボードのロジックアナライザタイミング、960.0us

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); 
}
4

2 に答える 2

4

腕の皮質 M4

Cortex M4 の FPU は単精度のみをサポートしていますが、コードでは倍精度を多く使用しています。これは、ハードウェアではなくソフトウェア計算を意味します。double変数と関数呼び出しを に変更しようとしましたfloatか?

于 2013-02-23T04:57:28.003 に答える
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% のデューティ サイクルが「可能な限り高速」になることを示すはずです。これを使用して、ボードが思うようにクロックされていることを確認します。

これは、Teensy 3.0 が基本的な命令を実行する時間が原因で遅いかどうか、または数学関数を実行するための命令が AVR よりも ARM に最適ではないかどうかを判断するのに役立ちます。この単純なプログラムでも遅い場合は、あなたが思っているようにクロックを上げていないのではないかと強く思います。

あなたのプローブがあなたが思っているように配線されていることを確認することをお勧めします.つまり、「遅い」チャネルは本当に「速い」ボードに配線されていますか?

于 2013-02-23T04:41:45.030 に答える