ORiN2 SDKのチュートリアルをC#で書く

# 1. 概要
ORiN2は、FA/ロボット向けの通信インタフェース。このページを参照。
[ORiNとは何か](https://www.orin.jp/whats-orin/)

ORiN2 SDKなどこちらの方の記事がよくまとまっている。
[ORiNについて調べてみた](https://qiita.com/laqiiz/items/9b2cc5b296821d7f10e1)

ユーザーズガイドに記載されていたサンプルを、Visual Studio 2017/C#に移植してみた。ORiN2 SDKのC#実装については、以下の動画が役に立った。
[ORiN2 - Read Variable Example (RC8 Controller)](https://www.youtube.com/watch?v=uifwiK3ql98&t=1s)

# 2. サンプルについて
元となっているサンプルは以下のユーザーズガイドから２つ。

[ORiN2 SDKユーザーズガイド Version 2.1.32](https://www.orin.jp/wp-content/uploads/2017/12/ORiN2SDK_UsersGuide_ja.pdf)

* 4.2 CAOチュートリアル
* 4.3 CRDチュートリアル

4.3は4.2からの続きになっている。
本記事ではソースコードの詳しい説明は省略するので、上記ユーザーズガイドを参照。

# 3. CAOチュートリアル

指定したIPアドレスに対してpingを実行し、到達可能かを調べるアプリを作る。

## 3-1. プロジェクトの新規作成

Visual Studio 2017を起動し、`ファイル>新規作成>プロジェクト`でプロジェクトを作成する。

1. 新しいプロジェクトダイアログが表示される
2. 左メニューから`インストール済み>Windowsデスクトップ`を選択
3. `Windows フォームアプリケーション(.NET Framework) Visual C#`を選択
4. プロジェクトの名前を`ORiNCaoApp`に指定
5. OKボタンを押す
![ORIN_newproj.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110430/428054af-3cef-8223-4cf1-96007e00b6a3.png)

## 3-2. フォームの作成
以下のコントロールを配置する。

(1) 入力用テキストボックス
Name: **textBox_IP_Address**
(2) メッセージ出力用テキストボックス
Name: **textBox_Message**
(3) pingボタン
Name: **button_Ping**
Text: **ping**

ついでにフォームの名前も変更し、サイズもいい感じにする。
Text: **ORiNCaoApp**
![ORiN_form.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110430/2443954f-1117-409a-d1d3-e6540ad4e8be.png)

## 3-3. コードを書く準備
ソリューションエクスプローラーからForm1.csを選んで右クリックし、`コードの表示`を選択する。
![ORiN_03_codeview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110430/f6c47f9a-3748-6bc5-3bda-efe0d6687285.png)

コード入力の画面になる。
![ORiN_04_codeview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110430/e3baebf6-245c-a285-f590-94da0ddd446c.png)

## 3-4. CAOライブラリを追加する
1. ソリューションエクスプローラーから`MyORiNApp`を選んで右クリック、`追加>参照`を選択する
![ORiN_05_add_reference.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110430/2d582ec2-36f4-9776-e313-f5daeaebed17.png)

2. 参照マネージャが表示されるので、左メニュー`COM>タイプライブラリ`を選択し、中央メニューから`CAO 1.0 Type Library`をチェックする
![ORiN_06_refman.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110430/360d764d-e4ae-6d2c-ff92-f5916ea91845.png)

3. OKボタンを押す

## 3-5. pingボタンのメソッドを追加

`Form1.cs[デザイン]`タブで、pingボタンをダブルクリックする。
`Form1.cs`タブのソースコードに、`button_Ping_Click()`が追加されたことを確認する。
以下のようになっているはず。

```C#:Form1.cs
namespace ORiNCaoApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button_Ping_Click(object sender, EventArgs e)
        {

        }
    }
}
```

## 3-6. コーディング

`Form1.cs`を以下のように編集する。

```C#:Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using CAOLib;

namespace ORiNCaoApp
{
    public partial class Form1 : Form
    {
        private CaoEngine eng;
        private CaoWorkspace caoWS;
        private CaoController icmpCtrl;
        private CaoVariable icmpVar;
        public Form1()
        {
            InitializeComponent();
            // CAOエンジンの生成
            eng = new CaoEngine();
            caoWS = eng.Workspaces.Item(0);
        }

        private void button_Ping_Click(object sender, EventArgs e)
        {
            // ICMPプロバイダに接続
            icmpCtrl = caoWS.AddController("Sample", "CaoProv.ICMP", "",
                "Host=" + textBox_IP_Address.Text);
            icmpVar = icmpCtrl.AddVariable("@ERROR_CODE");
            // pingの送信
            textBox_Message.Text = icmpVar.Value.ToString();
            caoWS.Controllers.Remove(icmpCtrl.Index);
        }
    }
}
```

最後に`Ctrl+Shift+S`で全て保存にする。

## 3-7. 実行

実行ボタンを押して実行する。

ORiNCaoAppのダイアログが表示されるので、上のテキストボックスに到達可能なIPアドレスを入力し、pingボタンを押す。到達できた場合は、以下のようにメッセージのテキストボックスにエラーコード`0`が表示される。
![ORiN_07_OK.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110430/5478effa-bf6a-15ce-4fa0-93a6eb526867.png)

到達できなかった場合は、以下のように0以外のエラーコードが表示される。
![ORiN_08_NG.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110430/32dc6695-4ed2-5e37-47ef-3d28eb6d84b3.png)

# 4. CRDチュートリアル

CAOチュートリアルの機能に追加して、CRDファイルでエラーコードとメッセージを登録し、エラーコードに対応したエラーメッセージを表示する。

## 4-1. tutorial.xmlを追加する
ソリューションエクスプローラから`ORiNCaoApp`を選択し、右クリックメニューで`追加>新しい項目`をクリックする。

![ORiN_09_new_item.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110430/475f0053-3704-0343-63e4-a2582a2c2935.png)

新しい項目の追加ダイアログが表示されるので、左メニューから`Visual C#アイテム>Data`を選ぶと候補が表示される。XMLを選択し、名前を`tutorial.xml`にする。
![ORiN_10_new_item.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110430/290723d9-b1a6-d04f-dacc-193f8c892754.png)

追加ボタンを押す。

## 4-2. tutorial.xmlを編集する

以下の内容を記載する。
先頭のcodingをutf-8に変更した以外は、元のサンプルからそのまま持ってくる。

```c#:tutorial.xml
<?xml version="1.0" encoding="utf-8" ?>
<CRD xmlns="http://www.orin.jp/CRD/CRDSchema"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.orin.jp/CRD/CRDSchema CRDSchema.xsd">
  <Controller name="PingStatus">
    <Variable name="0">
      <Value type="VT_BSTR">
        <bstrVal>IP_SUCCESS</bstrVal>
      </Value>
    </Variable>
    <Variable name="11001">
      <Value type="VT_BSTR">
        <bstrVal>IP_BUF_TOO_SMALL</bstrVal>
      </Value>
    </Variable>
    <Variable name="11002">
      <Value type="VT_BSTR">
        <bstrVal>IP_DEST_NET_UNREACHABLE</bstrVal>
      </Value>
    </Variable>
    <Variable name="11003">
      <Value type="VT_BSTR">
        <bstrVal>IP_DEST_HOST_UNREACHABLE</bstrVal>
      </Value>
    </Variable>
    <Variable name="11004">
      <Value type="VT_BSTR">
        <bstrVal>IP_DEST_PROT_UNREACHABLE</bstrVal>
      </Value>
    </Variable>
    <Variable name="11005">
      <Value type="VT_BSTR">
        <bstrVal>IP_DEST_PORT_UNREACHABLE</bstrVal>
      </Value>
    </Variable>
    <Variable name="11006">
      <Value type="VT_BSTR">
        <bstrVal>IP_NO_RESOURCES</bstrVal>
      </Value>
    </Variable>
    <Variable name="11007">
      <Value type="VT_BSTR">
        <bstrVal>IP_BAD_OPTION</bstrVal>
      </Value>
    </Variable>
    <Variable name="11008">
      <Value type="VT_BSTR">
        <bstrVal>IP_HW_ERROR</bstrVal>
      </Value>
    </Variable>
    <Variable name="11009">
      <Value type="VT_BSTR">
        <bstrVal>IP_PACKET_TOO_BIG</bstrVal>
      </Value>
    </Variable>
    <Variable name="11010">
      <Value type="VT_BSTR">
        <bstrVal>IP_REQ_TIMED_OUT</bstrVal>
      </Value>
    </Variable>
    <Variable name="11011">
      <Value type="VT_BSTR">
        <bstrVal>IP_BAD_REQ</bstrVal>
      </Value>
    </Variable>
    <Variable name="11012">
      <Value type="VT_BSTR">
        <bstrVal>IP_BAD_ROUTE</bstrVal>
      </Value>
    </Variable>
    <Variable name="11013">
      <Value type="VT_BSTR">
        <bstrVal>IP_TTL_EXPIRED_TRANSIT</bstrVal>
      </Value>
    </Variable>
    <Variable name="11014">
      <Value type="VT_BSTR">
        <bstrVal>IP_TTL_EXPIRED_REASSEM</bstrVal>
      </Value>
    </Variable>
    <Variable name="11015">
      <Value type="VT_BSTR">
        <bstrVal>IP_PARAM_PROBLEM</bstrVal>
      </Value>
    </Variable>
    <Variable name="11016">
      <Value type="VT_BSTR">
        <bstrVal>IP_SOURCE_QUENCH</bstrVal>
      </Value>
    </Variable>
    <Variable name="11017">
      <Value type="VT_BSTR">
        <bstrVal>IP_OPTION_TOO_BIG</bstrVal>
      </Value>
    </Variable>
    <Variable name="11018">
      <Value type="VT_BSTR">
        <bstrVal>IP_BAD_DESTINATION</bstrVal>
      </Value>
    </Variable>
  </Controller>
</CRD>
```

## 4-3. ソースコードの編集

以下のように修正する。
ただし、caoWS.AddController()のPathは各環境で修正すること。

```c#:Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using CAOLib;

namespace ORiNCaoApp
{
    public partial class Form1 : Form
    {
        private CaoEngine eng;
        private CaoWorkspace caoWS;
        private CaoController icmpCtrl;
        private CaoVariable icmpVar;
        private CaoController crdPingStatus;
        public Form1()
        {
            InitializeComponent();
            // CAOエンジンの生成
            eng = new CaoEngine();
            caoWS = eng.Workspaces.Item(0);
            crdPingStatus = caoWS.AddController("PingStatus", "CaoProv.CRD", "",
                "Path=//Mac/Home/Documents/project/ORiN2/Tutorial/CaoPingApp/CaoPingApp/tutorial.xml");
        }

        private void button_Ping_Click(object sender, EventArgs e)
        {
            // ICMPプロバイダに接続
            icmpCtrl = caoWS.AddController("Sample", "CaoProv.ICMP", "",
                "Host=" + textBox_IP_Address.Text);
            icmpVar = icmpCtrl.AddVariable("@ERROR_CODE");
            CaoVariable Result = icmpVar;
            // pingの送信
            CaoVariable stVar = crdPingStatus.AddVariable(Result.Value);
            textBox_Message.Text = stVar.Value.ToString();
            crdPingStatus.Variables.Clear();
            caoWS.Controllers.Remove(icmpCtrl.Index);
        }
    }
}
```

## 4-4. 実行

実行ボタンを押して実行する。

ORiNCaoAppのダイアログが表示されるので、上のテキストボックスに到達可能なIPアドレスを入力し、pingボタンを押す。到達できた場合は、テキストボックスにメッセージが表示される。

![ORiN_11_OK.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110430/0d1c119d-5aa7-3c22-33c4-03f532a50370.png)

到達できなかった場合は、以下のようにエラーメッセージが表示される。
![ORiN_12_NG.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110430/27a773fd-ee36-8caf-3337-97c80fa2f996.png)

以上