Microsoft Robotics Pad GUI 服务






4.61/5 (9投票s)
2007年9月9日
3分钟阅读

34830

603
一篇关于创建将使用 Microsoft Robotics Environment 的游戏手柄图形用户界面服务的文章。

引言
在之前的文章中,我们创建了一个游戏手柄服务。在这里,我们将创建另一个服务,该服务将提供关于手柄的图形反馈。即使对于这篇文章,请记住,这并不是一个CCR或DSS教程,并且对这些技术的良好了解将非常有用。在本文中,我假设您知道什么是消息、队列和服务。我也会跳过与之前服务相似的所有操作:服务创建、消息定义和消息处理。
基本思路是这样的:GUI服务可以接收一些消息,在相应的消息处理程序中,UI表单元素会被修改。
架构
我决定创建一个服务而不是修改手柄服务表单,以避免模块之间的紧耦合。GUI服务总是比单个表单更可重用。它也可以用于处理不同的硬件,例如操纵杆。关于消息的几句话:在此,服务被定义为所有Pad服务消息,因此我们在两个服务消息之间存在一对一的关系。我不认为这是与“手柄服务”的耦合,因为消息定义是相当抽象的。请记住,此服务假定摇杆范围在[-1,1]
中。请记住,服务消息具有相同的类名,但定义在两个不同的命名空间内。
图形用户界面
解决方案有两个项目
Pad.Controls
:包含一个简单的摇杆仪表用户控件PadGui
:包含消息定义和主窗体的服务。
主窗体有两个摇杆控件和 4 个标签,当按下按钮时,这些标签将变为红色。我们还有一个关于框。在主窗体内部,声明了几个属性来处理手柄状态。在StickGauge
类中,定义了两个属性来处理x
和y
摇杆位置。每当值更改时,都会执行Invalidate()
,并且相应的OnPaint
代码如下
private void panelPainter_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawEllipse(
new Pen(Brushes.Red), 5, 5, panelPainter.Width - 10,
panelPainter.Height - 10);
e.Graphics.FillEllipse(
Brushes.Red,
panelPainter.Width / 2 - 5, panelPainter.Height / 2 - 5, 10f, 10f);
int x = Convert.ToInt32((_x + 1) * panelPainter.Width / 2);
int y = Convert.ToInt32((_y + 1) * panelPainter.Height / 2);
e.Graphics.FillEllipse(Brushes.Blue, x - 5, y - 5, 10, 10);
e.Graphics.DrawCurve(new Pen(Brushes.Blue),
new Point[]{
new Point(panelPainter.Width/2,0),
new Point(x,y),
new Point(panelPainter.Width/2,panelPainter.Height),
});
e.Graphics.DrawCurve(new Pen(Brushes.Blue),
new Point[]{
new Point(0,panelPainter.Height/2),
new Point(x,y),
new Point(panelPainter.Width,panelPainter.Height/2),
});
txtXY.Text = string.Format("X({0})
Y({1})",Math.Round(_x,4),Math.Round(_y,4));
}
这并不是一个真正令人惊叹的图形体验,但它非常适合进行设备反馈。
服务
在服务启动阶段,我使用这个代码片段来启动一个窗口。请记住添加对程序集Ccr.Adapters.WinForms.dll的引用
using Microsoft.Ccr.Adapters.WinForms;
...
//Create Form
PadInfoForm _form = new PadInfoForm();
WinFormsServicePort.Post(new RunForm(
delegate()
{
return _form;
}
));
并且每当收到消息时,我们执行以下操作
[ServiceHandler(ServiceHandlerBehavior.Exclusive)]
public IEnumerator<ITask> RightStickUpdateHandler(RightStickUpdate rsUpd)
{
_form.RX = rsUpd.Body.Stick.StickValueX;
_form.RY = rsUpd.Body.Stick.StickValueY;
rsUpd.ResponsePort.Post(DefaultUpdateResponseType.Instance);
yield break;
}
分配给表单属性会导致摇杆更新。
结论
如果您正在询问谁向GUI服务发送消息,那么您就走对了路。在这里,我们创建了一个活动服务,该服务向其他服务发送通知。相反,这个服务有点像一个“被动服务”。它只接收消息,这样我们就可以编译和运行这个服务,但是只要我们不向这个服务发送消息,我们就不会得到任何反馈。这是我将要写的下一篇文章的目的。我将使用VPL来连接手柄服务和手柄GUI服务。这个服务的下一个改进将是一个WPF界面。
就是这样!
历史
- 2007年9月:首次发布