-
Robotics 使用Microsoft Robotics Studio 模拟真实世界
本文示例源代码或素材下载
本文将介绍以下内容:
构建机器人动画
构建环境
驱动机器人或模拟
创建实体
本文使用以下技术:
C#、Robotics Studio
目录
什么是模拟?
入门
运行模拟
实体及实体类型
以编程方式添加新实体
在 VSE 中定义新实体
创建实体类
创建网格
将网格转换为二进制格式
创建模拟服务
填充模拟场景
创建清单
运行模拟
构建不带有差动式驱动的实体
不要被它的名称骗了,Microsoft® Robotics Studio (MSRS) 可不单单能够掌控机器人。MSRS 大约在两年前由 Microsoft Research 发布,可用于为多种硬件设备构建基于服务的应用程序,但实际上却被日常业务应用程序开发人员忽略了。此工具包中提供的运行库应立即为 Windows® Communication Framework (WCF) 开发人员所熟悉。另外,它还具有可视化编程语言 (VPL) 工具和 Visual Simulation Environment (VSE)。
MSRS 提供了面向服务的运行库,以及设计和部署基于机器人的应用程序所需的工具。工具包中提供了面向首次涉足机器人世界的开发人员的可视化创作工具、教程和文档。商业开发人员必须支付少许费用购买此工具包,但爱好者和学术研究人员可以免费下载使用。
MSRS 运行库提供了两个基于 CLR 2.0 的较低级别的运行库。这两个运行库分别是分散软件服务 (DSS) 以及协调和并发运行库 (CCR)。DSS 是一种面向服务的轻型运行库,基于具象状态传输 (REST) 原理,用于启动 Web。CCR 是一个 Microsoft .NET Framework 库,支持异步处理。对于机器人应用程序而言,这非常重要,因为要不断在大量传感器和传动装置上发送和接收数据。
除运行库外,MSRS 工具包中还包括一个 VPL 工具。借助此工具,您只需将元素拖放到设计平面中即可构建机器人应用程序。MSRS 中还提供了 VSE,可用于体验涉及多个机器人和障碍物的复杂模拟。MSRS 的这部分功能是本文的重点。我将介绍可视模拟环境,并逐步介绍如何使用新的机器人实体创建模拟。值得高兴的是,您无需借助机器人来使用本文中的代码。这也是模拟最具吸引力之处;借助模拟,您无需在昂贵的硬件上投入资金即可达到学习的目的。
什么是模拟?
如果您不熟悉模拟,可以想象一本翻页的书 — 如果一本小书中的每页上都有一个图像,那么当连续快速地翻页时,您会发现这些图像在“移动”。模拟的工作方式与此类似。模拟包含一个或多个实体,每个实体都在帧内部呈现。帧即等效于翻页书中的一页纸,而帧的呈现速率取决于主机的图形卡。
翻页书和模拟之间的根本区别是,翻页书是静态的或可预测的,而模拟则不是。模拟的每个帧都是动态呈现的,实体在每一帧内部的受力并不总能提前获知。模拟的有用之处也正体现在这里。您可以使用机器人执行一个方案,然后查看机器人如何与现实世界交互。
入门
如果您尚未下载和安装 MSRS 工具包(位于 go.microsoft.com/fwlink/?LinkId=113902),请下载并安装。目前,MSRS 网站可提供其 1.5 版本的全新安装。这包括 MSRS 1.5 的完整版本以及所有可用更新。
虽然 MSRS 提供的一些模板是针对 Visual Studio® 2005 的,但即便您的计算机运行的是 Visual Studio 2008,也可以运行本文中提供的示例。您开发所用的计算机需要使用与 DirectX® 9.0 兼容的图形卡。特别值得一提的是,图形卡必须支持顶点着色器 VS_2_0 或更高版本,以及像素着色器 PS_2_0 或更高版本。对于大多数高端桌面和便携式计算机而言,只要能够运行如今的图形游戏,一般即已满足此配置要求。
如果您不能确定自己的图形卡支持什么配置,请访问 go.microsoft.com/fwlink/?LinkId=113904 获取图形卡的列表及其支持的着色器。此外,您还可以在 VSE 中安装 MSRS,并使用帮助菜单查看支持的像素着色器和顶点着色器。如果您尝试运行随 MSRS 提供或本文中包含的某个模拟,但您的屏幕显示为空白,则表示您的图形卡不兼容。
MSRS 使用 AGEIA PhysX 引擎为模拟环境提供物理支持。如果没有物理支持,模拟将没有任何用处,因为它无法表示自己尝试模拟的世界。例如,如果没有重力,实体就会四处飘荡。如果阅读 MSRS 随附的文档,您会发现其中介绍了由 AGEIA(请参见 ageia.com)提供的可选加速卡的用途。您不必专门为使用本文中提供的模拟而购买和安装此物理卡;AGEIA PhysX 软件引擎同样可以为您的模拟提供物理支持。
运行模拟
此时,您可能很希望看到模拟。在创建自己的模拟之前,您应尝试运行 MSRS 随附的某一个模拟。安装后,MSRS 将创建一个包含七个模拟的菜单文件夹。“基本模拟环境”是此文件夹中的第一个模拟,可呈现与图 1 类似的场景。
图 1 基本模拟环境
您可能认为基本模拟仅包括两个实体:地球仪和箱形物体。实际上,模拟场景中还包括用来代表主摄影机、地面、天空和太阳的实体。您可以通过在 VSE 菜单中依次单击“模式”和“编辑”来查看场景中包含哪些实体。
在图 2 所示的编辑模式下,您可以在左窗格中修改与各个实体相关的属性。借助这些属性即可完全控制实体,从名称到在模拟环境中的位置,无所不包。此外,您还可以通过这些属性精确控制实体的呈现方式,进而影响该实体在模拟中的显示方式。
图 2 可修改实体属性的编辑模式
返回到运行模式后,即可使用鼠标或箭头键来回移动模拟。这会更改主摄影机的视点,而此视点就是您查看模拟的视点。此处还需要重点提及的是,VSE 允许您使用不同的模式呈现场景。可视模式为默认模式,是模拟场景的真实视图。不过,“呈现”菜单项提供了线框、物理、组合或无呈现模式,可供您选择。
之所以提供“无呈现”选项,是因为呈现只是模拟的一个方面。运行模拟的最大价值在于实现各个实体之间的交互。因为从资源角度来讲,呈现模拟场景中的实体的费用非常昂贵,因此当场景中包含大量实体时,“无呈现”选项就会非常有用。
实体和实体类型
通过实体类型,您可以为特定类型的实体定义新实例。例如,基本模拟环境中的地球仪就是一种形状实体类型。实体类型充当新实体的模板,其中指定了与特定实体类型相关的属性。创建实体后,即可更改这些属性的值,但实体中包含哪些属性却是由实体类型定义的。
VSE 需要使用实体类型来向模拟添加实体。例如,若要添加一个机器人(如 iRobot 公司的 Create 机器人),您需要在 VSE 处于编辑模式时依次单击“实体”和“新建”,从而在其中添加一个新实体。这将打开一个“新建实体”对话框(请参见图 3)。
图 3 在“新建实体”对话框中插入新实体
iRobot 公司的 Create 机器人由 MSRS 提供实体类型,因此您只需使用“新建实体”对话框即可向模拟中添加新的 Create 机器人。在“新建实体”对话框中,您应在“类型”中选择“iRobotCreate”,然后输入唯一的名称,例如“创建实体”。单击“确定”后,Create 机器人将出现在模拟场景中。
以编程方式添加新实体
MSRS 提供了多种创建和使用模拟的方法。除 VSE 之外,您还可以通过创建 DSS 服务项目以编程方式向模拟中添加实体。MSRS 提供了一个 Visual Studio 模板,可用于新建 DSS 服务。安装 MSRS 后,在创建新的 Visual Studio 项目时,只选择 Simple Dss Service (1.5) 作为模板(请参见图 4)。
图 4 在 Visual Studio 2005 模板中新建 DSS 服务
使用模板新建 DSS 服务会随之创建两个类文件。实现类默认与项目同名,您可以在其中添加代码来创建新实体。以编程方式创建的模拟要求能够访问 Simple DSS Service 模板外部的程序集。因此,您将需要添加对图 5 中所列程序集的引用。
图 5 模拟项目附带的程序集
程序集名称 | 说明 |
PhysicsEngine | 提供对基本 AGEIA 软件物理引擎的访问。 |
RoboticsCommon | 提供对 PhysicalModel 命名空间的访问,此空间用于定义机器人的物理特征。 |
SimulationCommon | 提供对使用模拟和物理引擎时要用到的类型定义的访问。 |
SimulationEngine | 提供对模拟引擎的访问。 |
SimulationEngine.proxy | 代表模拟引擎的代理,当加载模拟引擎作为合作伙伴时会用到此代理。 |
添加引用后,您还需要在实现类文件中添加下列命名空间声明:
using Microsoft.Robotics.Simulation;
using Microsoft.Robotics.Simulation.Engine;
using engineproxy = Microsoft.Robotics.Simulation.Engine.Proxy;
using Microsoft.Robotics.Simulation.Physics;
using Microsoft.Robotics.PhysicalModel;
要了解模拟中需要哪些代码,应首先查看随 MSRS 提供的模拟教程。MSRS 安装程序的 samplessimulation 教程目录下提供的示例对应于 MSRS 安装的菜单中的模拟。例如,基本模拟环境与 SimulationTutorial1 项目相同。
如果使用 Visual Studio 2005 打开 SimulationTutorial1 项目,就可以查看用于创建基本模拟环境的代码。首先要注意的就是 Start 方法,启动服务后将自动调用此方法:
protected override void Start()
{
base.Start();
// Orient sim camera view point
SetupCamera();
// Add objects (entities) in our simulated world
PopulateWorld();
}
您可以在 Start 方法中添加代码来定义模拟环境。对于 SimulationTutorial1 项目,这包括设置摄影机和使用实体对象填充模拟场景。
除了主摄影机外,基本模拟环境中还包含用于代表天空、地面、箱形物体和地球仪的实体。用于插入地球仪(或带有纹理的球体)的代码已在图 6 中列出。
图 6 插入地球仪
void AddTexturedSphere(Vector3 position)
{
SingleShapeEntity entity = new SingleShapeEntity(
new SphereShape(
new SphereShapeProperties(10, // mass in kg
new Pose(), // pose of shape within entity
1)), //default radius
position);
entity.State.Assets.Mesh = "earth.obj";
entity.SphereShape.SphereState.Material =
new MaterialProperties("sphereMaterial", 0.5f, 0.4f, 0.5f);
// Name the entity
entity.State.Name = "detailed sphere";
// Insert entity in simulation.
SimulationEngine.GlobalInstancePort.Insert(entity);
}
AddTexturedSphere 方法中的第一行代码用于创建 SingleShapeEntity 的一个实例。此类型代表具有单一几何形状的实体(例如球形),当需要添加具有非常简单的物理几何体的实体时,它将非常有用。这样,我就可以创建重 10 千克或大约 4.5 镑的实体。
分配到此实体的网格是一个扩展名为 .obj 的对象文件。此对象文件使用 3D 图形编辑工具创建,并以别名对象格式导出。MSRS 要求网格对象文件采用此格式。您需要在 AddTexturedSphere 方法中实现的最后一项操作是向模拟环境插入球体实体。
在 VSE 中定义新实体
现在,我们来创建一个新的机器人实体,并用它来代表 Parallax 公司的 Boe-Bot 机器人。Boe-Bot 是一种支持两轮差动式驱动系统的小轮机器人(照片见图 7)。有关 Boe-Bot 的详细信息,请访问 Parallax 的网站,网址为 parallax.com。
图 7 Parallax 公司的 Boe-Bot
Boe-Bot 是 MSRS 支持的现有的几种机器人平台之一。这意味着 MSRS 安装中会包括一些基本服务,用于操纵 Boe-Bot 的驱动系统以及内置接触传感器。尽管 MSRS 中提供了适用于 Boe-Bot 的平台服务,但实际上并不包括 Boe-Bot 实体类型。
创建实体类
要创建适用于 Boe-Bot 的新实体类型,我需要添加一个派生自 DifferentialDriveEntity 的类。由于添加的类是从 DifferentialDriveEntity 类派生而来,因此我能够重用定义 Boe-Bot 在场景中来回移动时的行为方式的代码。用于创建 BoeBot 实体类型的代码如图 8 所示。
图 8 创建 BoeBot 实体类型
[DataContract]
public class BoeBot : DifferentialDriveEntity
{
Port<EntityContactNotification> _notifications =
new Port<EntityContactNotification>();
// Default constructor, used for creating the entity from XML
public BoeBot() { }
// Custom constructor for building model from hardcoded values.
// Used to create entity programmatically
public BoeBot(Vector3 initialPos)
{
MASS = 0.454f; //in kilograms (around 1 pound)
// the default settings approximate the BoeBot chassis
CHASSIS_DIMENSIONS = new Vector3(0.09f, //meters wide
0.09f, //meters high
0.13f); //meters long
FRONT_WHEEL_MASS = 0.01f;
CHASSIS_CLEARANCE = 0.015f;
FRONT_WHEEL_RADIUS = 0.025f;
CASTER_WHEEL_RADIUS = 0.0125f;
FRONT_WHEEL_WIDTH = 0.01f;
CASTER_WHEEL_WIDTH = 0.008f;
FRONT_AXLE_DEPTH_OFFSET = 0.01f; // distance from center of robot
base.State.Name = "BoeBot";
base.State.MassDensity.Mass = MASS;
base.State.Pose.Position = initialPos;
// chassis position
BoxShapeProperties motorBaseDesc =
new BoxShapeProperties("BoeBot Body", MASS,
new Pose(new Vector3(
0, // Use 0 for X axis offset
CHASSIS_CLEARANCE + CHASSIS_DIMENSIONS.Y / 2,
0.03f)), // minor offset in the z/depth axis
CHASSIS_DIMENSIONS);
motorBaseDesc.Material =
new MaterialProperties("high friction", 0.0f, 1.0f, 20.0f);
motorBaseDesc.Name = "Chassis";
ChassisShape = new BoxShape(motorBaseDesc);
// rear wheel is also called the castor
CASTER_WHEEL_POSITION = new Vector3(0, // center of chassis
CASTER_WHEEL_RADIUS, // distance from ground
CHASSIS_DIMENSIONS.Z / 2); // at the rear of the robot
RIGHT_FRONT_WHEEL_POSITION = new Vector3(
+CHASSIS_DIMENSIONS.X / 2,// left of center
FRONT_WHEEL_RADIUS, // distance from ground of axle
FRONT_AXLE_DEPTH_OFFSET); // distance from center, on z-axis
LEFT_FRONT_WHEEL_POSITION = new Vector3(
-CHASSIS_DIMENSIONS.X / 2,// right of center
FRONT_WHEEL_RADIUS, // distance from ground of axle
FRONT_AXLE_DEPTH_OFFSET); // distance from center, on z-axis
MotorTorqueScaling = 30;
// specify a default mesh
State.Assets.Mesh = "boe-bot.bos";
}
BoeBot 类的构造函数用于为在 DifferentialDriveEntity 类中定义的多个变量设置值。例如,将质量值设置为 0.454,代表质量以千克为单位。另外,使用宽度、长度和高度来定义 Boe-Bot 底盘。这些测量值通过称取机器人的实际重量、使用公制尺进行实际测量获得。
Boe-Bot 的位置通过一组坐标值进行定义,这组坐标值在创建实体时传入。这些坐标值代表 X、Y 和 Z 轴上的点。MSRS 模拟引擎使用右手坐标系,这会影响 Z 轴上的点的朝向。
BoeBot 构造函数还可定义底盘和实体中轮子的位置。DifferentialDriveSystem 类假定您的机器人将使用两个主轮和一个主要起平衡作用的小后轮。功率将分配到用于控制主轮的左、右马达。通过为每个轮子分配不同的功率级,可以确定各轮将向前、向后、向左还是向右移动。这与驱动物理机器人的方法相同。
模拟最具吸引力的一点就是:理论上,无论您的机器人是虚拟的还是真实的,驱动机器人和从传感器接收数据使用的代码都是相同的。用于模拟项目的部分代码同样可以重用于实际机器人。现在,您可能已注意到我说的是“理论上”。这是因为模拟技术无法完全模拟实际环境。模拟无法对干扰做出解释,此处的干扰是指一些出乎您意料的事情,如将障碍物的位置放错。
模拟的作用是让您非常真实地体验新机器人的设计效果,或模拟多个机器人的交互。这非常适用于资源有限而学员数量庞大的学术环境。
创建网格
每个实体都可以与网格关联,从而使实体呈现真实的外观。以地球仪为例,网格可以使地球仪实体显示为行星地球的外观。严格来说,没有必要将实体与网格关联,但对于复杂实体(例如机器人),则应该首选网格对象。
几乎任何 3D 图形编辑工具都可用于创建网格。在撰写本文时,我很幸运地获得了同事 Steve Grand 的帮助,他使用 3D 包 SoftImage(有关此工具的详细信息,请参见 softimage.com)为我创建了 Boe-Bot 网格。与此网格相关的文件均包含在本文随附的可下载的 .zip 文件中。要跟随本文的进度,请下载此 .zip 文件并提取上述文件,然后将 Boe-Bot 文件夹中的内容复制到 /store/media 目录下,此目录与本地 MSRS 安装相关。
SoftImage 能够将图像导出为 .obj 格式。并非所有包都有此功能。例如,MSRS 在其 Channel9 Wiki (go.microsoft.com/fwlink/?LinkId=114031) 中建议使用 3D 包 SolidWorks(请参见 solidworks.com)。但遗憾的是,SolidWorks 无法将图像导出为 .obj 格式,因此它建议使用 Blender (blender.org) 工具执行实际转换。当选择使用图形包创建网格文件时,请牢记这一点。
有关创建 Boe-Bot 网格的细节问题不在本文讨论范围之内,但您应知道它是通过连接多个多边形网格形状创建的。例如,金属底盘开始时是一个立方体形状,经修改后用于表示 Boe-Bot 的大小和形状。然后,添加其他圆柱体形状来代表各个轮子。建立结构,以将轮子与底盘绑定并允许整个对象作为一个单一形状来发挥功能。最终效果(如图 9 所示)是一个代表实际 Boe-Bot 的图像。
图 9 使用 SoftImage 创建 Boe-Bot 网格文件
将网格转换成二进制格式
MSRS 提供了一个命令行工具,可将 .obj 文件转换成经过优化的二进制文件,扩展名为 .bos。此文件类型的优点是加载速度比 .obj 文件快。您可以使用 MSRS 安装附带的命令提示符菜单项来访问命令行工具 Obj2bos.exe。
使用网格时,一定要记住:所有材料都用于为物理对象着色,并且每个实体都可以与一个或多个材料关联。因此,当创建 .obj 文件时,很可能需要包括扩展名为 .mtl 的其他材料文件。此外,还可能要包括用于创建纹理的图像文件。这些文件都必须复制到与 .obj 文件位置相同的位置,才能使用网格转换工具。
.obj 文件及所有关联文件都应放在与本地 MSRS 安装相关的 /store/media 目录下。由代码下载附带的与 Boe-Bot 网格关联的文件有:Aluminum.png、Boe-bot.mtl、Boe-bot.obj、BoebotWheel.png 和 Pcb.png。添加到 media 目录下之后,请打开 MSRS 命令提示符键入以下内容:
Obj2bos.exe /i:"storemediaBoe-bot.obj"
转换工具将创建一个名为 Boe-bot.bos 的文件,该文件位于 media 目录下。保留该文件的位置不动,因为稍后将引用此文件。
创建模拟服务
现在我已准备好创建 Boe-Bot 模拟服务。如果您遵从随本文下载的代码中的内容,请确保已经安装 MSRS,并将下载的代码添加到本地 MSRS 安装的 samples 文件夹下。
若要从头创建项目,则需要使用 Visual Studio 2005 模板创建一个新的 DSS 服务。您可以将该项目命名为 SimulatedBoeBot。除了之前提到的程序集引用外,您还需要添加对 Microsoft.Xna.Framework 的引用,并在 SimulatedBoeBot.cs 类文件的顶部添加以下命名空间引用:
using xna = Microsoft.Xna.Framework;
using xnagrfx = Microsoft.Xna.Framework.Graphics;
using xnaprof = Microsoft.Robotics.Simulation.MeshLoader;
Xna 框架供 MSRS 用于呈现实体。Xna 引用将用在定义 Boe-Bot 实体类型的代码中。MSRS 随附的所有实体类型都包含在 Microsoft.Robotics.Simulation.Engine 命名空间中。
填充模拟场景
每项模拟服务都有一项主要任务,就是向模拟场景中插入实体。此任务应在启动服务时执行,因此对 PopulateWorld 方法的调用通常添加到 Start 方法中。对于 Boe-Bot 模拟,PopulateWorld 方法如下所示:
private void PopulateWorld()
{
AddSky();
AddGround();
AddBoeBot(new Vector3(1, 0, 1));
AddBox(new Vector3(2, 1, 1));
}
AddSky 和 AddGround 方法用于设置 BoeBot 周围的环境。AddSky 方法将创建一个新的 SkyDomeEntity 类型,并将其插入模拟中。此外,还要向模拟中插入有向光线,用以代表太阳光(此方法的代码如图 10 所示)。
图 10 添加天空
void AddSky() {
// Add a sky using a static texture. We will use the sky texture
// to do per pixel lighting on each simulation visual entity
SkyDomeEntity sky = new SkyDomeEntity("skydome.dds",
"sky_diff.dds");
SimulationEngine.GlobalInstancePort.Insert(sky);
// Add a directional light to simulate the sun.
LightSourceEntity sun = new LightSourceEntity();
sun.State.Name = "Sun";
sun.Type = LightSourceEntityType.Directional;
sun.Color = new Vector4(0.8f, 0.8f, 0.8f, 1);
sun.Direction = new Vector3(0.5f, -.75f, 0.5f);
SimulationEngine.GlobalInstancePort.Insert(sun);
}
AddGround 方法使用 HeightFieldEntity 类型在零海拔处创建广阔的地面。随 MSRS 安装提供的纹理图像用于代表地面。此方法的代码如下所示:
void AddGround()
{
// create a large horizontal plane, at zero elevation.
HeightFieldEntity ground = new HeightFieldEntity(
"simple ground", // name
"03RamieSc.dds", // texture image
new MaterialProperties("ground",
0.2f, // restitution
0.5f, // dynamic friction
0.5f) // static friction
);
SimulationEngine.GlobalInstancePort.Insert(ground);
}
下一个要添加的是 Boe-Bot 实体。AddBoeBot 方法接受传入 Vector3 参数,此参数用于表示机器人的位置。此位置将传递给先前创建的 BoeBot 实体构造函数。AddBoeBot 方法也将启动模拟的 Boe-Bot 驱动器服务作为实体合作伙伴。此方法的代码如下所示:
void AddBoeBot(Vector3 pos)
{
BoeBot boeBot = new BoeBot(pos);
boeBot.State.Name = "SimulatedBoeBot";
// Start simulated Boe-Bot Drive service
CreateService(
drive.Contract.Identifier,
Microsoft.Robotics.Simulation.Partners.CreateEntityPartner(
"http://localhost/" + boeBot.State.Name));
SimulationEngine.GlobalInstancePort.Insert(boeBot);
}
最后一个要添加的实体是一个实心箱形物体,用于代表障碍物。AddBox 方法将基于 SingleShapeEntity 类型创建一个箱形实体。此方法的代码如图 11 所示。
图 11 创建箱形实体
void AddBox(Vector3 position)
{
Vector3 dimensions =
new Vector3(0.2f, 0.2f, 0.2f); // meters
// create simple movable entity, with a single shape
SingleShapeEntity box = new SingleShapeEntity(
new BoxShape(
new BoxShapeProperties(
100, // mass in kilograms.
new Pose(), // relative pose
dimensions)), // dimensions
position);
box.State.MassDensity.Mass = 0;
box.State.MassDensity.Density = 0;
// Name the entity. All entities must have unique names
box.State.Name = "box";
// Insert entity in simulation.
SimulationEngine.GlobalInstancePort.Insert(box);
}
创建清单
多数服务都将与其他服务结成合作伙伴来访问本服务所需的功能和数据。在实现类的顶层使用合作伙伴属性引用这些合作伙伴服务。例如,Boe-Bot 模拟服务将与模拟引擎服务成为合作伙伴。包括此合作伙伴声明的此代码如下所示:
//Simulation Engine Port
[Partner("Engine",
Contract = engineproxy.Contract.Identifier,
CreationPolicy = PartnerCreationPolicy.UseExistingOrCreate)]
private engineproxy.SimulationEnginePort _engineStub =
new engineproxy.SimulationEnginePort();
DSS 服务使用基于 XML 的文件(称为清单)列出与基本服务相关的合作伙伴服务。这可以告知 MSRS 运行库基本服务应如何加载这些合作伙伴服务并与之交互。尽管此清单是基于 XML 的文件,可以使用基于文本的编辑器进行编辑,但最好使用 MSRS 随附的 DSS 清单编辑器。DSS 清单编辑器是一个可视工具,允许您将合作伙伴服务拖放到设计图面上。在使用 DSS 清单编辑器之前,需要成功编译基本服务。这将创建一个程序集文件,供 DSS 清单编辑器使用。
加载 DSS 清单编辑器后,将在左窗格中提供所有可用服务的列表。开始之前,您需要从可用服务列表中找到基本服务,并将该服务的一个实例拖动到设计图面上。如果对 Boe-Bot 模拟服务执行此操作,设计图面中将包含代表 SimulatedBoeBot 服务的节点和代表模拟引擎服务的子节点。
MSRS 安装的 samples 文件夹中包含了多个服务,其中的一项服务 SimpleDashboard 可用作模拟机器人的控制面板。SimpleDashboard 允许您启动用于控制机器人特定功能的其他服务。例如,SimulatedBoeBot 服务中的代码只使用包括 Boe-Bot 在内的一些实体来填充模拟场景,服务中的所有代码都不会实际移动机器人。您需要从驱动服务中借用此代码。
为加载和使用简单的控制板,必须从服务列表中找到 SimpleDashboard 的一个实例,将其拖动到设计图面的底部,从而将其添加到清单中。最终效果应如图 12 所示。最后,还需要将此清单保存到 SimulatedBoeBot 服务的项目目录,覆盖名为 SimulatedBoeBot.mainfest.xml 的清单。
图 12 DSS 清单编辑器中的最终清单版本
运行模拟
现在,您已为运行 SimulatedBoeBot 服务做好了一切准备,只需单击 Visual Studio 2005 菜单中的“调试”和“运行”即可开始运行。首先,应显示命令提示符窗口。
加载服务后,应立即显示另外两个窗口。简单控制板的界面是一个 Windows 表单,其中包括多个组框。表单右侧(请参见图 13)有“远程结点”组框。要开始运行,您需要在计算机文本框中输入本地计算机 (localhost) 的名称,然后单击“连接”。这将开始与 SimulatedBoeBot 服务建立连接,并加载实体合作伙伴服务,例如目录列表框中显示的驱动服务。
图 13 在虚拟世界中驱动 Boe-Bot
驱动服务用于为控制 Boe-Bot 的轮子提供动力。这样,您就可以使用虚拟控制杆控件或与计算机相连的实际控制杆在模拟中来回移动 Boe-Bot。双击列表框中显示的 SimulatedBoeBot 项目即可开始移动。随后,您就可以使用鼠标拖动圆形虚拟控制杆,此控制杆位于简单控制板表单的左上角。
您可能要经过一段时间后才会习惯使用虚拟控制杆控件(有关模拟效果的外观,请参见图 14)。练习来回移动 Boe-Bot,并查看它与箱形障碍物碰撞时的情形。您可以进入编辑模式,选择其中一个实体,调整其部分属性以查看这对该实体有何影响。在模拟环境中体验一段时间,感觉一下轮子的工作方式。
图 14 在虚拟环境中操纵模拟的 Boe-Bot
构建不带差动式驱动的实体
在本文中,我介绍了如何创建名为 Boe-Bot 的新机器人实体。由于 Boe-Bot 使用差动式驱动系统控制机器人轮子,所以我能够创建从 DifferentialDriveEntity 类派生的实体类型。这样,我就可以重用 MSRS 提供的代码来控制使用此类型的驱动系统的机器人。
如果您要模拟使用其他驱动系统的机器人,则首先要添加代表该驱动系统的类。例如,部分机器人使用三轮式驱动系统。在这种情况下,只有一个前轮用于移动机器人,两个侧轮分别连接两个单独的马达,用于在各自的方向上操纵机器人。
为使此类系统可用于模拟世界或真实世界,需要创建一个类,用于说明此类型的驱动系统。此操作的步骤不在本文的讨论范围之内,但 MSRS 允许您针对此类型的方案提供相应步骤。此类可扩展性是使 MSRS 对机器人学研究人员的价值非比寻常的原因之一。MSRS 可以扩展为支持任何类型的硬件平台。
Sara Morgan 是 2007 年度 Office Communications Server 领域的 Microsoft MVP。她的第一本著作《Building Intelligent .NET Applications》于 2005 年出版。除了与人合著多个 Microsoft 培训工具包之外,她最近还发布了《Programming Microsoft Robotics Studio》。目前,她在 CoroWare.com 担任机器人软件工程师。