2

この質問は特定の言語に関するものではなく、むしろ問題を解決するものです。

メソッドをロボットに送信し、センサーデータを要求するタイマーがあります。

一部のセンサーは非常に重要であり、ほとんどの場合要求される必要がありますが、他のセンサーはそれほど重要ではありませんが、時々読み取る必要があります。

だから私が私のタイマーを持っていて、タイマーの中でそれが以下のコードによって返されるメソッドを要求すると想像してください:

Timer_Tick()
{
   AskForData(SensorRequestList())
}

private int _tCliffState = 0;
private int _tCliffSignal = 0;
private int _tLight = 0;
//and 7 other 

private byte[] SensorRequestList()
{
    if (_tCliffState <= 5)
    {
        _tCliffState++;
        return RequestCliffStates();
    }
    if(_tCliffSignal < 1)
    {
        _tCliffSignal++;
        return RequestCliffSignals();
    }
    if(_tLight < 1)
    {
        _tLight++;
        RequestLightSignals();
    }
    //and more ifs!


    //reset all
    _tCliffState = 0;
    _tCliffSignal = 0;
    _tLight = 0;
    //...
}

私が10のメソッドを持っている場合、最良の方法は何ですか。たとえば、1,2,3、... 10のように名前が付けられ、優先度も1,2,3...10のようになります。

より優先度の高いメソッドがより多く要求されることを確信できる素晴らしいパターンをどのように達成できますか?このパターンのようなもの:

1,1,1,2,1,3,1,1,4,1,1,1,2,1,1,1,3,1,1,1,4 and so on

4

3 に答える 3

2

データが定期的に受信される場合(たとえば、ミリ秒に1回、1秒に1回、1日に1回、1週間に1回など)、一定期間にわたって収集されたデータを分析する方が簡単です。

パフォーマンスを保証する必要が生じた場合(少なくとも1秒ごとにセンサーからの応答がない場合、ロボットがミスを犯す可能性があります)、プログラムを何らかの定期的なスケジュールで実行すると、より簡単になります。

これらの理由から、一定数のリクエストを繰り返し行い、各固定数のリクエストの間に一定の間隔を空けてデータを収集することをお勧めします。私は通常、そのような固定数のリクエストをフレームと呼びます。

非常に重要なセンサーの読み取り値をフレーム内の独自のスロットに割り当てて、フレームごとに収集されるようにします。重要度の低いセンサー読み取り値がそれらの間でスロットを共有するようにします。たとえば、8つのセンサー読み取り値が1つのスロットを共有し、それぞれが8フレームごとに1回収集されるようにすることができます。生活をより複雑にしたい場合は、サブスロットを共有できるため、8つの非常に重要でないセンサー読み取り値がサブスロットを共有し、それぞれが64フレームごとに1回収集されます。

一般に、生の値だけでなくデータにもある種のタイムスタンプを保持することをお勧めします。実際、一部のシステムは、フレームごとにスナップショットを取得し、このスナップショットの時刻を記録し、スナップショットの時刻の後に値を読み取るように調整しています。次に、すべての値は同じ瞬間に取得された読み取り値であり、この瞬間がわかります。

于 2013-01-06T08:16:31.577 に答える
1

使用しているようなカウンター手法の問題は、特定の時間に複数のメソッドを実行できる可能性があることです。問題を軽減するための解決策は、カウンターを停止し、すべての修飾されたメソッドをキューに入れ、キューが空になるまで、次のタイマーイベントのためにキューに入れられた各メソッドを選択することです。空になったら、カウントプロセスを再開して、新しいメソッドのセットを選択できます。

メソッドキューintを格納するためにを使用した、可能な実装(テストされていないコード)は次のとおりです。

Timer_Tick() {
   AskForData(SensorRequestList());
}

private int _state[NUM_METHODS]; // initialized to 0
private int _priority[NUM_METHODS]; 
private int _flags; // initialized to 0
private (byte [])(*_methods)[NUM_METHODS]; // array of pointer to functions, 
                                                                            // runnables, etc.


private byte[] SensorRequestList() {
     do {
        for (int i = 0; i < NUM_METHODS; ++i)
            if ((1 << i) & _flags){
                _flags &= ~(1 << i);
                _state[i] = 0;
                return _method[i]();
           }

         for (i = 0; i < NUM_METHODS; ++i){
            _state[i]++;
            _flags |= (_state[i] >= _priority[i]) << i;
        }
    } while (!_flags);
}

この実装では、メソッドの数をプラットフォームよりも少なくする必要sizeof(int) * 8があります(1バイトあたり8ビットを想定)。より多くの数の実際のキューを使用するように簡単に切り替えることができます。

のリセットの代わりに_state0次を使用できます。

  _state[i] -= _priority[i];

カウンターをローリングし続けますが、これには、選択した要素がどのようにキューに入れられるかについて、さらに注意が必要です。

于 2013-01-06T19:18:48.510 に答える
1

これは、合理的な何かを与えるはずのヒューリスティックの擬似コードの説明です。

  1. すべての優先順位を合計し、それを合計と呼びます。
  2. リストを優先度の高い順に並べ替えます。
  3. サイズ合計の空の配列を初期化します。
  4. 最初の(最も優先度の高い)要素から始めて、その要素のインスタンスをその優先度と同じ数だけリストに追加します。間隔を選択するときは、ラップアラウンドを考慮に入れてください。
  5. 配列内の空き領域のみを考慮して、優先度の低い要素を続行します。
  6. tティックの後、配列内の位置t%sumに対応するセンサーデータを要求します。

優先度1..10の10個の一意の要素A..Jを使用した例を使用すると、sum = 55が得られ、配列は[A、B、C、D、E、A、C、B、F、G、Aです。 、D、C、B、E、A、H、F、C、B、A、D、E、G、C、A、B、I、D、E、A、C、B、F、H、A 、D、C、B、E、A、G_、F、C、B、A、D、E、I、G、B、D、F、H、J]必要。

于 2013-01-07T23:32:59.137 に答える