複数のOutputSlotから単一のInputSlotへの接続

ここは、Arbor開発者への要望を行うためのフォーラムです。

This is a forum for requesting Arbor developers.
ooee

複数のOutputSlotから単一のInputSlotへの接続

Postby ooee » 2017/07/25 08:36

いつもお世話になっています。

Subjectの件、技術的に可能でしたら実装をご検討いただけないでしょうか。

User avatar
caitsithware
管理人
Posts: 82
Joined: 2015/08/17 12:41

Re: 複数のOutputSlotから単一のInputSlotへの接続

Postby caitsithware » 2017/07/25 09:49

要望ありがとうございます。

InputSlotに複数のOutputSlotを接続するとなると、どのラインの値を使用するのかが問題になりそうです。
複数接続のうちの一番新しく変更された値を使いたい、という認識で間違いないでしょうか?

また、現状での対応策として、
ParameterContainerに一時的なパラメータを作成しておき、必要に応じて格納&取り出しという方法で同様の挙動が作成できるかと思います。
もしまだお試しになってませんでしたら、一度試してみてください。

ooee

Re: 複数のOutputSlotから単一のInputSlotへの接続

Postby ooee » 2017/07/25 13:31

>InputSlotに複数のOutputSlotを接続するとなると、どのラインの値を使用するのかが問題になりそうです。
>複数接続のうちの一番新しく変更された値を使いたい、という認識で間違いないでしょうか?
はい、その認識で間違いありません。

>また、現状での対応策として、
>ParameterContainerに一時的なパラメータを作成しておき、必要に応じて格納&取り出しという方法で同様の挙動が作成できるかと思います。
対応策、ありがとうございます。
一度試してみます。

ooee

Re: 複数のOutputSlotから単一のInputSlotへの接続

Postby ooee » 2017/07/27 08:54

>ParameterContainerに一時的なパラメータを作成しておき、必要に応じて格納&取り出しという方法で同様の挙動が作成できるかと思います。
これでももちろん実現できるのですが、状態間の値のやり取りがわかりづらくなるのと、値をやり取りするのにある意味グローバルなところに
一時変数を用意する点が気になっています。(贅沢言ってすいません)

ひとつ気になったことがあるのですが、InputSlotの値が更新されたタイミング(時間)の取得は可能でしょうか?
もし可能なら、InputSlotの配列から一番新しく更新された値を取り出してOutputSlotに入れるというスクリプトを間にかませば、Subjectの内容が実現できそうだと思ったもので。

User avatar
caitsithware
管理人
Posts: 82
Joined: 2015/08/17 12:41

Re: 複数のOutputSlotから単一のInputSlotへの接続

Postby caitsithware » 2017/07/27 11:47

ooee wrote:ひとつ気になったことがあるのですが、InputSlotの値が更新されたタイミング(時間)の取得は可能でしょうか?
もし可能なら、InputSlotの配列から一番新しく更新された値を取り出してOutputSlotに入れるというスクリプトを間にかませば、Subjectの内容が実現できそうだと思ったもので。


更新タイムスタンプは現在保持していないため取得できません。
また、いまのところArborの内部処理では演算ノードの再演算のタイミング等の問題で、どの接続が最新データか選択すべきかを保証するすべがない感じです。
(内部的な問題点については最後に記述)

対処方法としては、データスロットのカスタマイズを行い、タイムスタンプ付きクラスを受け渡すことでステートからの出力タイムスタンプを得る方法があります。

まず、以下のようにスロットを定義します。

Code: Select all

[System.Serializable]
public class TimestampInt
{
    public int value;
    public float timestamp;
   
    public TimestampInt(int value)
    {
        this.value = value;
        this.timestamp = Time.time;
    }
}
 
[System.Serializable]
public class OutputSlotTimestampInt : OutputSlot<TimestampInt>
{
}
 
[System.Serializable]
public class InputSlotTimestampInt : InputSlot<TimestampInt>
{
}


そして、StateBehaviourで入出力します。

Code: Select all

public class TimestampIntBehaviour : StateBehaviour
{
   public InputSlotTimestampInt input;
   public OutputSlotTimestampInt output;

   public override void OnStateBegin()
   {
      int value = 0;
      TimestampInt data = null;
      if (input.GetValue(ref data))
      {
         Debug.LogFormat("{0} : {1}", data.value, data.timestamp);
         value = data.value;
      }
      output.SetValue(new TimestampInt(value+1));
   }
}
 


こんな感じでいかがでしょうか。

■Arbor内部的な問題点について

データスロットは演算ノードとも接続できるため、演算ノードが間に入っている場合の更新タイムスタンプは取得しようとしたタイミング(=計算されるタイミング)になってしまいます。

なぜ演算ノードがあると取得時に計算する仕様なのかは以下の通りです。

  • 出力するたびに演算ノードでの再計算は無駄が多いため、最終的に取得しようとしたときのみ演算が最適。
  • 複数のステートから演算ノードに接続して演算する場合、1つのステート側からの出力時よりも取得時のほうが準備が整っている。
  • Calculator.OnCheckDirty()がtrueを返すようになっており、常に再演算する場合もある。

このような仕様なので演算ノードが間にある場合に複数接続すると、どのラインを選択すべきかは不定になります。
例えば、こんな繋げ方とか・・・
MultiSlot.png
MultiSlot.png (88.3 KiB) Viewed 86 times

取得しようとしたタイミングで両方の演算ノードが処理されて、結果、Input側でのタイムスタンプは同じになってしまいます。

内部的に「最初に接続されている方」と決めても良いですが、どちらが最初かぱっと見わからないので難しいですね。

ひとまず、タイムスタンプについては1つの判断基準にはなるかと思いますので、
複数接続はひとまず保留としてもタイムスタンプ自体は追加しようとかと思います。

ooee

Re: 複数のOutputSlotから単一のInputSlotへの接続

Postby ooee » 2017/07/28 01:18

スクリプトまで用意まで例示していただいて、ありがとうございます。
タイムスタンプ付きクラスを被せる方法で、実現したいことができそうなので試してみようと思います。


Return to “Request : 要望”

Who is online

Users browsing this forum: No registered users and 1 guest

cron