<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>https://wiki.lessokaji.com/index.php?action=history&amp;feed=atom&amp;title=MDCS%E5%BC%95%E6%93%8E%E9%80%82%E9%85%8D%E6%9C%BA%E5%99%A8%E4%BA%BA%E5%85%A5%E9%97%A8%E6%95%99%E5%AD%A6</id>
	<title>MDCS引擎适配机器人入门教学 - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.lessokaji.com/index.php?action=history&amp;feed=atom&amp;title=MDCS%E5%BC%95%E6%93%8E%E9%80%82%E9%85%8D%E6%9C%BA%E5%99%A8%E4%BA%BA%E5%85%A5%E9%97%A8%E6%95%99%E5%AD%A6"/>
	<link rel="alternate" type="text/html" href="https://wiki.lessokaji.com/index.php?title=MDCS%E5%BC%95%E6%93%8E%E9%80%82%E9%85%8D%E6%9C%BA%E5%99%A8%E4%BA%BA%E5%85%A5%E9%97%A8%E6%95%99%E5%AD%A6&amp;action=history"/>
	<updated>2026-04-15T15:57:20Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://wiki.lessokaji.com/index.php?title=MDCS%E5%BC%95%E6%93%8E%E9%80%82%E9%85%8D%E6%9C%BA%E5%99%A8%E4%BA%BA%E5%85%A5%E9%97%A8%E6%95%99%E5%AD%A6&amp;diff=890&amp;oldid=prev</id>
		<title>Artheru：​创建页面，内容为“//todo...  MDCS分别为4个AGV主要组件，分别为  * '''Medulla，硬件适配软件'''。提供通信抽象，通过插件对接各类硬件。开发者适配车型后，应使用遥控器应用进行遥控车体、试验IO等操作，来验证适配结果，确保硬件适配层不会故障或崩溃。 工作内容：网络或串口编程、适配CAN卡驱动、报文适配、编写遥控逻辑、上下位信号设计、基础动作逻辑 * '''Detour，…”</title>
		<link rel="alternate" type="text/html" href="https://wiki.lessokaji.com/index.php?title=MDCS%E5%BC%95%E6%93%8E%E9%80%82%E9%85%8D%E6%9C%BA%E5%99%A8%E4%BA%BA%E5%85%A5%E9%97%A8%E6%95%99%E5%AD%A6&amp;diff=890&amp;oldid=prev"/>
		<updated>2025-03-13T13:37:05Z</updated>

		<summary type="html">&lt;p&gt;创建页面，内容为“//todo...  MDCS分别为4个AGV主要组件，分别为  * &amp;#039;&amp;#039;&amp;#039;Medulla，硬件适配软件&amp;#039;&amp;#039;&amp;#039;。提供通信抽象，通过插件对接各类硬件。开发者适配车型后，应使用遥控器应用进行遥控车体、试验IO等操作，来验证适配结果，确保硬件适配层不会故障或崩溃。 工作内容：网络或串口编程、适配CAN卡驱动、报文适配、编写遥控逻辑、上下位信号设计、基础动作逻辑 * &amp;#039;&amp;#039;&amp;#039;Detour，…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;//todo...&lt;br /&gt;
&lt;br /&gt;
MDCS分别为4个AGV主要组件，分别为&lt;br /&gt;
&lt;br /&gt;
* '''Medulla，硬件适配软件'''。提供通信抽象，通过插件对接各类硬件。开发者适配车型后，应使用遥控器应用进行遥控车体、试验IO等操作，来验证适配结果，确保硬件适配层不会故障或崩溃。 工作内容：网络或串口编程、适配CAN卡驱动、报文适配、编写遥控逻辑、上下位信号设计、基础动作逻辑&lt;br /&gt;
* '''Detour，定位软件'''。''这部分只需要配置。''SLAM导航、二维码、UWB定位相关程序。主要给出车体位姿。开发者应通过Detour对车体各传感器进行标定。若使用激光SLAM导航则应建图。 工作内容：配置传感器、建图、传感器位置标定：óó&lt;br /&gt;
* '''Clumsy，自动驾驶系统'''。定义AGV所有可用的动作，如差速行走、舵轮行走、侧移行走、自动找工位或托盘、调姿取放货等。开发者应通过Clumsy插件实现适配AGV的所有动作，并通过测试类验证动作实现。 工作内容：车体定义、基础动作编程和参数定义、动作测试编程、智能动作编程&lt;br /&gt;
* '''Simple，AGV调度系统'''。Simple是个完备的静态调度系统，即小车路径一旦下发无需更改，调度系统保证小车运行到终点。开发者需要开发业务插件，定义车型、针对车型的路径搜索约束器（限制车型的行走路线，如不可直角拐弯等）、针对车型的路径编程器（将路径转为具体的AGV动作序列）、路径搜索的约束条件、并实现场景所需的业务逻辑；还需要在Clumsy插件编写动作对接函数，使得Simple可以调用Clumsy中定义的动作。开发者的场景实现应具有模拟功能，从而可以上线前模拟验证调度业务的正确性，然后再在实际场景中上线实际业务功能。 工作内容：路径图绘制、路径搜索其发器、路径编程器、业务逻辑的正确编写（对接按钮盒、派发任务、维护任务状态等）&lt;br /&gt;
&lt;br /&gt;
== 工程组织方法介绍 ==&lt;br /&gt;
'''约定1：首先应命名车型名称。'''解决方案中存在一个称为CartAdapters的文件夹，应创建一个以该车型命名的文件夹，并把ClumsyPilot（自动驾驶工程）和MedullaAdapter（硬件适配工程）放入文件夹中。如图下所示：&lt;br /&gt;
&lt;br /&gt;
'''约定2：源代码目录结构必须符合规范'''：所有的车型需要放到CartAdapters中，每个车型一个目录，并且把所有车型资料放到对应的文件夹中。（如车型图片、对接协议、文档等）。&lt;br /&gt;
&lt;br /&gt;
'''约定3：编译结果目录结构必须符合规范'''：编译结果一律放到build文件夹中，每个车型一个文件夹。场景均放到AGVScene目录中，每个场景（项目）设立一个文件夹。&lt;br /&gt;
&lt;br /&gt;
'''指南1：如何在解决方案中新建车型。'''以车型FY2104001为例。&lt;br /&gt;
&lt;br /&gt;
首先要复制MedullaAdapter和ClumsyPilot两个工程：即从已有工程或模板中复制到CartAdapters/FY2104001目录里。然后解决方案里新建一个解决方案文件夹，命名为FY2104001，然后分别导入MedullaAdapter和ClumsyPilot两个工程。最后在build目录里新建一个名为“FY2104001“的文件夹。&lt;br /&gt;
&lt;br /&gt;
随后进行改名：ClumsyPilot工程的程序集名称/默认命名空间改名为”FY2104001_c”，MedullaAdapter工程的程序集/默认命名空间名称改为“FY2104001_m”。&lt;br /&gt;
&lt;br /&gt;
然后将这两个工程的生成事件中的“生成后事件命令行”修改正确：这个命令行将输出文件导出到build/FY2104002目录中，方便管理。&lt;br /&gt;
&lt;br /&gt;
== Medulla开发方法介绍 ==&lt;br /&gt;
'''约定3：MedullaAdapter工程需要实现全部硬件通信、IO读取和处理、和基础运动指令下发功能。'''以下是一些例子：&lt;br /&gt;
&lt;br /&gt;
向某个电机驱动器发送1000rpm的转速、向某个舵轮发送转到45度角并以3000rpm速度行走、货叉向上举升、如果近距离避障雷达触发了则向所有电机下发0速度，左转弯时亮起转向灯。&lt;br /&gt;
&lt;br /&gt;
MedullaAdapter适配完成后，应得到可通过NetRemote应用该程序或AGV遥控器App，人工遥控执行所有AGV动作的程序。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''约定4：MedullaAdapter工程中命名要规范'''。以某型号为BL21001的车型为例：&lt;br /&gt;
&lt;br /&gt;
其中，设备定义类为BL21001Cart。&lt;br /&gt;
&lt;br /&gt;
BL21001有三种轮询，分别控制IO、电机、音乐和电池。命名为IORoutine,MotorRoutine和MusicRoutine和BatteryRoutine。&lt;br /&gt;
&lt;br /&gt;
BL21001的遥控逻辑为BL21001Remote&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''定义1：上位IO（UpperIO）指人工或自动驾驶自动下发的字段'''，如下发速度、下发方向盘角度、下发的避障选择区域等。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''定义2：下位IO（LowerIO）指从硬件读取的字段'''，如实际轮速、实际转角、障碍物信号、电池电量等。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''指南5：如何MedullaAdapter中定义设备。'''以FY2104002Cart为例：&lt;br /&gt;
&lt;br /&gt;
''应指定上位IO和下位IO。''使用AsUpperIO标记字段来指定字段是上位IO，若改字段无上位遥控信号达到300ms，且设置了timeOutReset=true，则会自动恢复为设定的默认值。下位IO使用AsLowerIO标记。这些字段需要设为public。&lt;br /&gt;
&lt;br /&gt;
''可以指定一些监控量，''需要使用IOObjectMonitor进行标记。这些字段需要设为public。&lt;br /&gt;
&lt;br /&gt;
设备可以指定一些UI调试按钮方法，使用IOObjectUtility进行标记。这些方法需要设为public。&lt;br /&gt;
&lt;br /&gt;
''设备应该指定“梯形图逻辑”，''即周期性执行的代码。使用UseLadderLogic来指定。UseLadderLogic需要指定logic类型和scanInterval扫描周期。Logic所指定的梯形图类型需要继承LadderLogic&amp;lt;FY2104002Cart&amp;gt;，并实现Operation方法。&lt;br /&gt;
&lt;br /&gt;
''设备应指定一个遥控器程序。''使用UseManualController来指定，其中manualController类型为遥控逻辑类，它需要继承ManualController&amp;lt;FY2104002Cart&amp;gt;，并实现Operation方法。&lt;br /&gt;
&lt;br /&gt;
''可以指定初始化变量，''使用AsInitParam进行标记。这些变量可以在Medulla的启动脚本startup.iocmd中设置，从而在调用Init时可以使用。&lt;br /&gt;
&lt;br /&gt;
''设备应实现初始化方法Init()''。可以做各个设备的初始化操作。&lt;br /&gt;
&lt;br /&gt;
''可以映射一些空方法到UI界面上，使用IOObjectUtility标记''。这些方法会出现在Medulla的界面中，用户可点击调用，一般用来测试。&lt;br /&gt;
&lt;br /&gt;
以下展示了一个设备的定义案例&lt;br /&gt;
&lt;br /&gt;
'''指南6：如何编写“梯形图逻辑”，应编写什么功能？'''梯形图逻辑是间隔若干ms执行的逻辑程序。需要实现Operation方法，方法里可以使用cart变量来访问设备定义类的成员变量。Operation里应处理报文。如设备初始化方法中启动了一个串口，开发者应在Operation里对串口进行读操作，来解析设备报文，存入下位IO变量（LowerIO）；并根据上位IO变量（UpperIO）组织报文，并对串口进行写操作。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''指南7：遥控逻辑是什么？如何编写遥控逻辑？'''Medulla支持多种不同的控件，如按钮、开关等，可以映射为NetRemote程序的虚拟控件、AGV遥控App的虚拟控件、或Xbox手柄上的物理按钮盒摇杆。遥控逻辑可以访问到这些控件的按键情况和数值，从而可向UpperIO写入数据，进而遥控车体运动。&lt;br /&gt;
&lt;br /&gt;
以某型号为BL21001的包夹式AGV为例。&lt;br /&gt;
&lt;br /&gt;
遥控逻辑类名为BL21001MRemote，继承ManualController&amp;lt;BL21001Cart&amp;gt;。&lt;br /&gt;
&lt;br /&gt;
遥控逻辑类可以定义多个遥控控件，包括Button(按钮)，Switch(开关)，Knob(旋钮)，Stick(摇杆)，DPad(四向键)，Throttle(推杆)，DThrottle(双向推杆)。定义的遥控控件需要增加AsControlItem标记。&lt;br /&gt;
&lt;br /&gt;
以下是个例子：&lt;br /&gt;
&lt;br /&gt;
遥控逻辑类需要实现Operation方法。需要读取定义的控件值，并向一些UpperIO赋值（如，根据direction摇杆的方向对“下发舵轮角度”进行赋值）。&lt;br /&gt;
&lt;br /&gt;
控件的值会在执行Operation方法前自动更新。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''指南9：如何上机验证'''：以FY2104001_m为例&lt;br /&gt;
&lt;br /&gt;
1.将Medulla程序放入指定目录：如桌面startup文件夹。将Medulla的全部核心程序复制入目录，将生成的Medulla适配程序（FY2104001_m.dll）放入plugins文件夹，如果适配程序还引用了其它的库，也一并放入plugins文件夹。&lt;br /&gt;
&lt;br /&gt;
2.编写Medulla启动配置脚本：startup.iocmd文件。基础的例子如下&lt;br /&gt;
&lt;br /&gt;
loader = io load plugins\CartActivator.dll&lt;br /&gt;
&lt;br /&gt;
loader setp com COM1&lt;br /&gt;
&lt;br /&gt;
cart = loader load plugins\FY2104001_m.dll&lt;br /&gt;
&lt;br /&gt;
ui=io load plugins\WinMedulla.dll&lt;br /&gt;
&lt;br /&gt;
ui Show&lt;br /&gt;
&lt;br /&gt;
解析：&lt;br /&gt;
&lt;br /&gt;
使Medulla加载车体加载器插件：loader = io load plugins\CartActivator.dll&lt;br /&gt;
&lt;br /&gt;
设置初始化变量：loader setp com COM1，这里com是FY2104001_m中定义的初始化变量（标记为AsParamInit）&lt;br /&gt;
&lt;br /&gt;
加载FY2104001_m中的车体定义，并把车体记为cart对象。&lt;br /&gt;
&lt;br /&gt;
加载Medulla自带的UI界面库：ui=io load plugins\WinMedulla.dll&lt;br /&gt;
&lt;br /&gt;
显示UI：ui Show&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''说明2：Medulla使用方法和启动配置脚本进一步说明'''&lt;br /&gt;
&lt;br /&gt;
Medulla主程序启动后，逐行地执行脚本，有三种语法：&lt;br /&gt;
&lt;br /&gt;
调用语句：如cart reset，使cart对象调用reset方法。&lt;br /&gt;
&lt;br /&gt;
创建对象语句：如cart = loader load plugins\FY2104001_m.dll，使loader调用load方法，参数为plugins\FY2104001_m.dll，结果对象名称记为cart。&lt;br /&gt;
&lt;br /&gt;
变量赋值语句：如cart.thOffset=1.2，使cart对象的thOffset成员变量赋值为1.2&lt;br /&gt;
&lt;br /&gt;
Medulla的命令语句可以在UI界面的命令执行选项卡直接执行。&lt;br /&gt;
&lt;br /&gt;
加载ui对象后，ui Show方法会弹出硬件控制台界面，会将控制台关闭。如果需要再打开，可以选择ui对象，并点击ShowConsole按钮。&lt;br /&gt;
&lt;br /&gt;
一般AGV可能还有其它传感器要接入Medulla，如激光雷达、3D相机等。以下列举一些常用的代码配置：&lt;br /&gt;
&lt;br /&gt;
加载激光雷达插件：&lt;br /&gt;
&lt;br /&gt;
lidar = io load plugins\LidarController.dll&lt;br /&gt;
&lt;br /&gt;
定义一个名为frontlidar的倍加福R2000雷达对象：&lt;br /&gt;
&lt;br /&gt;
frontlidar = lidar init PnFR2kLidar 192.168.1.11&lt;br /&gt;
&lt;br /&gt;
定义一个名为backlidar的山东科力雷达对象：&lt;br /&gt;
&lt;br /&gt;
backlidar = lidar init sdkeli 192.168.1.11&lt;br /&gt;
&lt;br /&gt;
定义一个名为forklidar的西克Nano Scan雷达对象&lt;br /&gt;
&lt;br /&gt;
forklidar= lidar init sicknano&lt;br /&gt;
&lt;br /&gt;
定义一个名为frontlidar3d的速腾聚创RS16多线雷达对象&lt;br /&gt;
&lt;br /&gt;
frontlidar3d = lidar init RSLidar16 192.168.1.2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
指南10：遥控验证方法：&lt;br /&gt;
&lt;br /&gt;
遥控验证用于检测Medulla的硬件对接程序是否正常工作。开发者应尝试使用遥控器指挥小车做各类动作，检查动作的流畅性，并检查基础动作逻辑是否正确（如拍急停应当停车等）&lt;br /&gt;
&lt;br /&gt;
注意Medulla在遥控时，就不再响应自动驾驶程序Clumsy所下发的信号了。&lt;br /&gt;
&lt;br /&gt;
'''1.  打开Medulla硬件对接程序，截图如下。'''&lt;br /&gt;
&lt;br /&gt;
其中红框中标出的cart即为开发的Medulla适配对象。中间的列表列举了所有开发者定义的变量（包括上位变量、下位变量和监控变量），并实时更新显示。用户还可以通过打开监视窗口来图形化地检测变量中的数值变量。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2.  使用NetRemote桌面版遥控器进行遥控验证。应用截图如下：'''&lt;br /&gt;
&lt;br /&gt;
点击激活遥控后，AMR遥控器开始向Medulla输出遥控数据。如该遥控器是一个潜伏顶升可旋转托盘的AGV遥控画面。用户首先设定速度（即speed控件），点击上下左右键可以控制小车前进、后退、左转、右转。按住up顶升、按住down下降。滑动rot可控制转盘。&lt;br /&gt;
&lt;br /&gt;
另外，可以绑定键盘按键以方便控制。点击“编辑“，右键弹出菜单即可绑定按键。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3.可使用手机遥控器App进行遥控验证，并作为AGV遥控的主要方式。'''&lt;br /&gt;
&lt;br /&gt;
其截图如下：&lt;br /&gt;
&lt;br /&gt;
类似的，用户可以激活遥控器，或点击编辑模式编辑遥控器面板。遥控器面板编辑完成后可导出为二维码并建议粘贴在车体上，供后续扫码识别使用。&lt;br /&gt;
&lt;br /&gt;
手机遥控器具备两种连接模式，一种是Wifi连接，另一种是蓝牙连接。推荐使用蓝牙连接方式，连接较为简单方便。手机App中点击连接按钮，即显示以下画面：&lt;br /&gt;
&lt;br /&gt;
查看Medulla界面，cart对象中属性页的BTName项，此项的值为该工控机的蓝牙名称（可自行在操作系统设置里更改）。App中选中正确的设备，等待连接完成后即可遥控。连接设定也可以导出为二维码并建议贴在车体上，供后续连接使用。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
指南11：其它外设定义&lt;br /&gt;
&lt;br /&gt;
说明2中已列举了激光雷达插件的使用方法。Medulla还支持以下种类的传感器输入：&lt;br /&gt;
&lt;br /&gt;
USB摄像头，使用方法：&lt;br /&gt;
&lt;br /&gt;
1.  进入命令执行窗口，输入camera = io load plugins\USBCamera.dll&lt;br /&gt;
&lt;br /&gt;
2.  回到对象窗口，可看到当前检查到的摄像头列表。&lt;br /&gt;
&lt;br /&gt;
3.  进入命令执行窗口，输入camera detail Chicony_USB2.0_Camera，查看所有支持的模式。&lt;br /&gt;
&lt;br /&gt;
4.  我们选择模式2(640*480分辨率)，并指定彩色输出。在startup.iocmd中配置&lt;br /&gt;
&lt;br /&gt;
camera = io load plugins\USBCamera.dll&lt;br /&gt;
&lt;br /&gt;
usbcam = camera init Chicony_USB2.0_Camera 2 true&lt;br /&gt;
&lt;br /&gt;
即可创建一个名为usbcam的摄像头对象。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
工业摄像头驱动，支持海康威视、大华、Basler等工业相机，使用方法：&lt;br /&gt;
&lt;br /&gt;
在startup.iocmd中配置：&lt;br /&gt;
&lt;br /&gt;
mv = io load plugins\MVCamera.dll&lt;br /&gt;
&lt;br /&gt;
maincam=mv initMono CA013&lt;br /&gt;
&lt;br /&gt;
其中CA013是摄像头型号，initMono为以单色方式启动。若相机是彩色相机，则使用initColor方法。&lt;br /&gt;
&lt;br /&gt;
== Clumsy开发介绍 ==&lt;br /&gt;
Clumsy是小车的运动控制组件。开发者需要做的是：定义运动控制的输入输出变量、定义参数表、定义动作、定义动作测试例程，并提供调度接口。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
约定1：车型参数表命名规范：以某背负式差速小车BSD10LS为例，命名为BSD10LSConfigs.cs，包含若干个由[FieldMember]标记的参数，为该小车可配置的参数。任何参数都可以放到该类中，Clumsy自动识别、提供默认调参程序并存储参数至clumsy.json配置文件中。支持的参数类型为string/int/float/double，即字符串和数值类。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
指南1：车型定义文件如何编写？以某背负式差速小车BSD10LS为例：&lt;br /&gt;
&lt;br /&gt;
1.     车型定义文件，命名为BSD10LSDef.cs，包含类BSD10LSDef，继承自PilotDefinition&amp;lt;BSD10LSConfigs&amp;gt;。该文件从MedullaAdapter工程中设备定义类BSD10LSCart.cs中摘抄标记了AsUpperIO和AsLowerIO的字段。这些字段中，AsLowerIO字段会自动更新，AsUpperIO字段会自动下发。&lt;br /&gt;
&lt;br /&gt;
2.     车型定义文件还需要重写Init方法，这个方法会在Clumsy启动时调用。此外还需要重写DriveStop方法，在小车静息或遇故障停车时，写入的下位变量。常用的初始化操作包括：&lt;br /&gt;
&lt;br /&gt;
a)      在BSD10LSDef中设定一个静态变量self，并在启动时设置self=this，使得其它类可以访问BSD10LSDef的实例。&lt;br /&gt;
&lt;br /&gt;
b)      调用ClumsyLib.Capture();从而启动Clumsy的传感器采集功能。&lt;br /&gt;
&lt;br /&gt;
c)       启动前台UI或者创建线程后台上报数据等。&lt;br /&gt;
&lt;br /&gt;
3.     需要给车型定位文件增加欲使用的控制方法标记。支持三种控制方法：&lt;br /&gt;
&lt;br /&gt;
a)      CanDifferentialDrive，即差速驱动方法。使用该标记，需要指定type为一个继承了DifferentialWriterClass的差速速度下发类。如：&lt;br /&gt;
&lt;br /&gt;
开发者需要实现WriteLR方法，向驱动器中写入速度。&lt;br /&gt;
&lt;br /&gt;
b)      CanSteeringDrive，即单舵轮驱动方法，类似的，使用该标记需要指定type为一个继承了SteeringWriterClass的舵轮速度下发类。该类除了写入舵轮速度外，还应反馈舵轮角度和速度（角度是必须的，若无速度则可以用刚刚下发的速度代替）。角度单位是度，速度无单位。如：&lt;br /&gt;
&lt;br /&gt;
c)       CanOmniDrive，即全向驱动方法。使用该标记需要指定type为一个继承了OmniWriterClass的全向速度下发类。下发的速度会指定X速度、Y速度和旋转方向（旋转方向为逆时针旋转角度）。须开发者判断如何具体分解速度和旋转至各个舵轮或麦克纳姆轮上，若遇到奇点或限位问题（如舵轮角度已打满，须反向灯），也需要开发者自行计算。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
指南2：如何定义动作并测试动作？动作将参数打包好并返回动作序列（为一个Generator函数），使得可以通过Clumsy的DriveTask进行管理。&lt;br /&gt;
&lt;br /&gt;
1.     如使用内置的一些算法，如LeftRightWheelTracking（差速追踪模型），一个例子如下：&lt;br /&gt;
&lt;br /&gt;
上述代码打包了在BSD10LSConfigs中定义的部分参数，随后可以继续对返回的LeftRightWheelTracking对象进行设置路径点操作，从而完成整套动作。&lt;br /&gt;
&lt;br /&gt;
2.     可以设置一个UI按钮来测试定义的动作。如以下代码所示：&lt;br /&gt;
&lt;br /&gt;
以上代码定义会在Clumsy界面中产生一个测试UI按钮：&lt;br /&gt;
&lt;br /&gt;
接下来用户可在界面上拖拽来查看行走效果，从而进行调参。&lt;br /&gt;
&lt;br /&gt;
3.     如果定义一些更简单的方法，如顶升等，则使用MovementDefinition来定义。该类的Get方法应是一个Generator函数，通过yield return true来表示动作计算完毕待下发，释放CPU资源并等到下一个周期再继续计算动作。这种方法可以使得动作编排足够紧凑，不需要复杂的状态机设计即可完成复杂的动作序列。如：&lt;br /&gt;
&lt;br /&gt;
通过Get()方法返回一个IEnumerable&amp;lt;bool&amp;gt;对象后，可产生一个DriveTask类进行动作执行。例子如下：&lt;br /&gt;
&lt;br /&gt;
4.     Clumsy使用了Nancy作为内置的HTTP服务器。若需要Clumsy额外提供接口给上下位应用，则可以编写一个WebAPIContainer类，并继承NancyModule，从而增加API。&lt;br /&gt;
&lt;br /&gt;
5.     Clumsy若使用Simple作为调度系统，则需要实现AGV.cs类。类中包含所有调度能够使用的动作命令，一般至少包括一个行走命令（如可命名为Go）。&lt;br /&gt;
&lt;br /&gt;
内置运动控制方法介绍见MDCS参考手册。&lt;br /&gt;
&lt;br /&gt;
== Simple开发介绍（待续） ==&lt;/div&gt;</summary>
		<author><name>Artheru</name></author>
	</entry>
</feed>