# 设置信号绑定

[导入模型与约束及自定义运动组件](https://utc.gitbook.io/umt-manual-book/primary/automaticgenerate/importconstraint)教程已经介绍了如何导入模型并自动绑定运动约束。 接下来我们将介绍如何绑定导入的模型与信号。以下教程将以OPC\_UA协议接入为例，演示如何将信号接入到孪生场景中

## 添加信号服务器

示例场景的机械臂信号储存在OPCUA服务器上。按照以下步骤添加OPCUA服务器

### 从UMT Menu 打开 `Signal/Manager`

点击`Signal Tools`窗口的 `Signal Manager`按钮弹出信号管理窗口

![](https://590671407-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcjRYQBrGBRq9cuhWqyze%2Fuploads%2Fgit-blob-b487157ef1ff5c7d870755cba51d0240dbce5eb0%2FAddManager.png?alt=media)

### 添加OPCUA服务器并配置

点击`+ Add`按钮并选择`OPCUAServer`，随后将弹出OPCUA服务区配置界面如下图

![](https://590671407-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcjRYQBrGBRq9cuhWqyze%2Fuploads%2Fgit-blob-4eac2c79370bdb92dcced30de7046082d7f554ae%2FAddOpcua.png?alt=media)

在 `Endpoint url`填入机械臂信号的OPCUA服务器 `opc.tcp://124.222.222.252:62541/SampleServer`

完成配置信息后，点击`Connect`按钮开始连接。

![](https://590671407-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcjRYQBrGBRq9cuhWqyze%2Fuploads%2Fgit-blob-d7dfa12a405e44862049b20ba09464dd31dc930c%2FConnected.png?alt=media)

连接成功后可以看到`Status` 变为`Connected`。OPCUA服务器上发布的信号将出现在浏览框，用户在可在浏览框中浏览信号 勾选`Connect On Play`

> 当`Connect On Play`该选项被勾选时，该服务器将会在Unity切换到Runtime模式时自动连接。 否则则需要手动点击`Connect`按钮

> 测试OPC\_ua 信号源无需认证即可连接。但是在大多数工业场景中，认证是必不可少的。可以在OPC\_ua 配置窗口中勾选`With Authentication`，开启认证输入，填入用户名和账户

## 订阅机械臂信号

OPC\_ua协议中会提供非常丰富的设备状态数据，但并不是所有的数据都适合用于数字孪生。因此，我们需要选择所需要的信号进行订阅。这样可以减少信号与机电设备的匹配工作量，提高程序效率。如图找到所选信号配合使用鼠标左键配合Shift, Ctrl进行多选，然后右击鼠标添加订阅到对应订阅组中

![](https://590671407-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcjRYQBrGBRq9cuhWqyze%2Fuploads%2Fgit-blob-567bcc4b89146088b755a2637ed3fc5f63907ccb%2FAddSub.png?alt=media)

订阅完成的信号将出现在`Manager`右侧区域，以列表形式展示。如下图：

![](https://590671407-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcjRYQBrGBRq9cuhWqyze%2Fuploads%2Fgit-blob-5cd4b4c9d2333a8d7ef2563bac1dbc2d1e2accb7%2Fsubed.png?alt=media)

信号列表中，`Topic`栏对应OPC\_ua信号的`Topic`。`Topic`是OPC\_ua用来标记独立信号的地址。`Type`对应OPC\_ua传输来的信号类型。本教程中，所有信号从服务器发送时的类型均为`Byte Array(16bit)`。`ReinterpreAs`栏为数字孪生程序所需要使用的类型。用户可以进行自定义类型转换，可以通过Bolt进行转换（稍后会介绍），默认类型为`Byte Array`。

## 订阅信号类型转换

所有，接收到的机械臂信号类型是长度为2的`Byte Array(16bit)`， 我们可以通过ReinterpretAs栏将其预转换为Int16类型。预转换能够方便后续信号的处理。当然这一步也可以使用Bolt进行转换（稍后会介绍）。

![](https://590671407-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcjRYQBrGBRq9cuhWqyze%2Fuploads%2Fgit-blob-8badb151079006c4518e232e2726bbccab0fb86e%2Freinter.png?alt=media)

## 信号绑定与处理

教程中，信号与孪生体的对应关系如下表：

| 信号                                                      | **孪生体**                                    | **作用**         |
| ------------------------------------------------------- | ------------------------------------------ | -------------- |
| **ns=2;s=169.254.200.200\_5020/InputRegisters\_0\_1**   | 1-Base\_NiryoOne\_V2.0-1 - Wheel Joint     | 机械臂一轴角度(mrad)  |
| **ns=2;s=169.254.200.200\_5020/InputRegisters\_1\_1**   | 2-Shoulder\_NiryoOne\_V2.0-2 - Wheel Joint | 机械臂二轴角度(mrad)  |
| **ns=2;s=169.254.200.200\_5020/InputRegisters\_2\_1**   | 3-Arm\_NiryoOne\_V2.0-4 - Wheel Joint      | 机械臂三轴角度(mrad)  |
| **ns=2;s=169.254.200.200\_5020/InputRegisters\_3\_1**   | 4-Base\_NiryoOne\_V2.0-4 - Wheel Joint     | 机械臂四轴角度(mrad)  |
| **ns=2;s=169.254.200.200\_5020/InputRegisters\_4\_1**   | 5-Forearm\_NiryoOne\_V2.0-3 - Wheel Joint  | 机械臂五轴角度(mrad)  |
| **ns=2;s=169.254.200.200\_5020/InputRegisters\_5\_1**   | 6-Wrist\_NiryoOne\_V2.0-4 - Wheel Joint    | 机械臂六轴角度(mrad)  |
| **ns=2;s=169.254.200.200\_5020/InputRegisters\_500\_1** | Gripper                                    | 夹爪状态(0关闭，1打开)  |
| **ns=2;s=169.254.200.200\_5020/InputRegisters\_531\_1** | BeltSurface                                | 传送带状态(0停止，1运行) |

对于机械轴信号`ns=2;s=169.254.200.200_5020/InputRegisters_[0-5]_1`，收到的信号单位为信号mrad，我们需要转换为degree(用float表示)

对于夹爪信号`ns=2;s=169.254.200.200_5020/InputRegisters_500_1`和传送带`ns=2;s=169.254.200.200_5020/InputRegisters_531_1`，我们需要将Int16转化为Boolean, 夹爪信号代表是否打开，传送带信号待变是否运转

在实际开发过程中，每一个信号的作用与对应设备等信息，需要数字孪生开发者与机电工程师反复沟通确认得到。

### 信号绑定

一个信号要与一个孪生对象产生控制关系，需要首先创建一个绑定关系，绑定关系会将信号的内容下发到孪生对象，并指挥孪生对象的运动。

信号绑定关系流程如下:

* 点击信号列表中的某一信号，右侧会显示信号绑定设置窗口
* 点击右下角`+`号，创建一个绑定关系

![](https://590671407-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcjRYQBrGBRq9cuhWqyze%2Fuploads%2Fgit-blob-9bbe5b83f11e077b1784eba4d18340fc196363c5%2FCreate_SignalItem.png?alt=media)

绑定关系列表窗口中有四列信息展示分别为:

| Item名称       | 作用               |
| ------------ | ---------------- |
| ID           | 每一个信号绑定关系的唯一编码   |
| GameObject   | 信号绑定关系对应需要驱动的孪生体 |
| Bolt         | Bolt可视化转换逻辑      |
| EventHandler | 信号绑定关系调用的孪生体接口   |

将孪生体使用鼠标拖入绑定关系列表的Gameobject一栏中，并选择所需的EventHandler。如图中，我们设定了一个机械臂一轴，并与其中一个信号进行绑定。由于机械臂的轴用WheelJoint控制，因此我们在EventHandler中选择`SetValue(System.Single)`。

![](https://590671407-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcjRYQBrGBRq9cuhWqyze%2Fuploads%2Fgit-blob-9621bf1f2603cd0a0878b3404106e0c9b6c849ed%2FBind_Digitaltwin_Go.png?alt=media)

### 信号转换

由于孪生体的控制接口输入类型是固定的，但是不同的设备传输的协议不相同，因此还需要对特定信号转换为孪生体支持的控制类型。例如示例中，机械臂的输入类型为单浮点型，单位为度。而信号预转换输出类型为Int16，单位为毫弧度(mrad)。因此我们需要对转换逻辑进行描述。

点击信号列表中的Bolt按钮

![](https://590671407-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcjRYQBrGBRq9cuhWqyze%2Fuploads%2Fgit-blob-9f9011393278e2aedbf7c689076a2fd5f5004c09%2FBolt_Open.png?alt=media)

初次打开，窗口中为默认的信号转换描述。该逻辑会尝试将预转换之后的数值传输到孪生体的接口，如果类型不对，Bolt将会抛出异常。但不会影响程序运行。

> 在点击之后，如果第一次点击，会创建Bolt的描述文件，因此需要10秒左右的时间间隔。 如果打开之后发现窗口中没有图示的可视化节点，可以通过点击窗口右上角的`Overview`快速定位到逻辑描述。

![](https://590671407-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcjRYQBrGBRq9cuhWqyze%2Fuploads%2Fgit-blob-1e969bc7ee4420bb2ccb3ecc3737e70c9199595e%2FBolt_Default_Win.png?alt=media)

#### 角度转换

修改Bolt窗口中的节点连接，如下图。在鼠标拖拽，创建`Convert、Multiply、Float`等节点，并按照图示进行连线。示例中机械臂的轴向均可使用该方法转换。更多创建方法可以参考[Bolt Units and Ports](https://docs.unity3d.com/2019.3/Documentation/Manual/bolt-units.html)

![](https://590671407-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcjRYQBrGBRq9cuhWqyze%2Fuploads%2Fgit-blob-0d01db5b4a887dfb5b242b18d53f9016494e3554%2FBolt_Convert_2_Angle.png?alt=media)

#### 开关转换

在窗口中创建`Convert to Boolean`节点，并按照图示连接。示例中，传送带和夹爪状态均可使用该方法。

![](https://590671407-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcjRYQBrGBRq9cuhWqyze%2Fuploads%2Fgit-blob-3cd79d194b6c7b28f4b935e1230f90730b7db7f5%2FBolt_Convert_2_Bool.png?alt=media)

如果在创建时发现没有Convert节点，需要通过设置引入系统默认的Convert窗口。打开Editor->Project Settings->Visul Scripting。在窗口中添加Convert。

![](https://590671407-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcjRYQBrGBRq9cuhWqyze%2Fuploads%2Fgit-blob-b9bcd3e6d96312cc6a16a4df39c88e8c113f2bfa%2FBolt_Add_Node.png?alt=media)

## 运行

按照相同步骤完成其余5个信号的绑定后,点击Play按钮切换Unity到Play模式，将能看到机械臂在信号的驱动下运动起来

![](https://590671407-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcjRYQBrGBRq9cuhWqyze%2Fuploads%2Fgit-blob-028929d96c5795ba82038db1830cff0530560797%2FDone.gif?alt=media)
