예제 #1
0
        static void Main(string[] args)
        {
            //作業ディレクトリだけでなく"dlls"というフォルダのライブラリも実行中に参照できるよう設定を変更
            PathModifier.AddEnvironmentPaths(Path.Combine(Environment.CurrentDirectory, "dlls"));

            //HelloWorldの対象とするマシンのアドレスをIPとポート(ポートは通常9559)で指定
            string address = "tcp://xxx.xxx.xxx.xxx:9559";
            var    session = QiSession.Create(address);


            //ALAnimatedSpeech::sayに渡す典型的なannotated text
            var text = new QiString(
                "^start(animation/Stand/Gestures/Hey_1) " +
                "Hello, this is a typical sample sentence for animated say module, to check some autonomous motion suited for the conversation " +
                "^wait(animation/Stand/Gestures/Hey_1)"
                );

            //AnimatedSay::sayの第二引数に渡す、モーションのモードを表す単一ペアの辞書
            var config = QiMap <QiString, QiString> .Create(new[]
            {
                new KeyValuePair <QiString, QiString>(
                    new QiString("bodyLanguageMode"),
                    new QiString("contextual")
                    )
            });

            var animatedSayArgs = QiTuple.Create(text, config);

            Debug.WriteLine(animatedSayArgs.Signature);
            Debug.WriteLine(animatedSayArgs.Dump());


            var animatedSpeech = session.GetService("ALAnimatedSpeech");

            //1. CallメソッドはQiMap型のシグネチャをハンドリングできない(.NETラッパー側の不備)ので
            //     低レイヤ呼び出しのCallDirectを用いる

            //2. "(sm)"はqi Frameworkの型を表す文字列で、
            //   関数の引数に文字列("s")と、動的型("m")からなるタプル(全体を囲うカッコ)であることを示す
            //   詳細はは公式の型-文字列対応表(http://doc.aldebaran.com/libqi/api/cpp/type/signature.html)などを参照

            //3. CallDirectの戻り値は非同期形式(QiFuture)なのでGetValue()での結果取得により明示的にブロックして同期処理化
            //   (非同期で使いたければGetValue()を後で呼ぶ)
            var res = animatedSpeech
                      .CallDirect("say::(sm)", animatedSayArgs.QiValue)
                      .GetValue();

            //Void型が返却されるのを確認
            Debug.WriteLine(res.ContentValueKind);
        }
        public async void StartMonitor()
        {
            if (_monitorObserver != null)
            {
                return;
            }

            await Task.Run(() =>
            {
                var vd = _connectionService
                         .CurrentSession?
                         .GetService(CameraMonitor.ALVideoDeviceServiceName);
                if (vd == null)
                {
                    return;
                }

                //設定をそのまま入れて購読開始
                var subscribeName = new QiString(vd.Call(
                                                     CameraMonitor.SubcsribeMethodName,
                                                     new QiString(CameraMonitor.SubscriberDefaultName),
                                                     new QiInt32((int)SelectedCamera),
                                                     new QiInt32((int)SelectedResolution),
                                                     new QiInt32((int)SelectedColorSpace),
                                                     new QiInt32(SelectedFps)
                                                     ).GetString());

                //上の設定は途中でGUIから変更食らうのでコッチは固定するのがポイント
                var camType = SelectedCamera;
                var camRes  = SelectedResolution;
                var camCs   = SelectedColorSpace;

                double intervalSec = 1.0 / SelectedFps;

                int maxParallel   = MaxParallelDownload;
                int parallelCount = 0;

                _monitorObserver = Observable.Timer(TimeSpan.FromSeconds(intervalSec), TimeSpan.FromSeconds(intervalSec))
                                   .Subscribe(_ =>
                {
                    if (parallelCount >= maxParallel)
                    {
                        return;
                    }

                    var res = vd.Call(CameraMonitor.DownloadMethodName, subscribeName);
                    //通信途絶すると恐らくエラーを食らうハズ
                    if (res.ValueKind == QiValueKind.QiUnknown)
                    {
                        return;
                    }

                    //※本来は初期設定時の値を使えるハズだが、変なタイミングで設定を変える可能性もゼロではないので
                    //いちおうColorSpaceとかバイト配列のサイズに関連する情報を確保する
                    int width   = res[0].GetInt32();
                    int height  = res[1].GetInt32();
                    int channel = res[2].GetInt32();
                    var cs      = (CameraColorSpace)res[3].GetInt32();

                    byte[] data = res[6].GetRaw();

                    if (width *height *channel != data.Length)
                    {
                        return;
                    }

                    CameraImage = CameraMonitor.GetFreezedImageFromBytes(data, camType, cs, camRes);
                });
            });
        }