Microsoft Robotics Studio-便笺服务(译文)
By robot-v1.0
本文链接 https://www.kyfws.com/games/microsoft-robotics-studio-a-pad-service-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 6 分钟阅读 - 2984 个词 阅读量 0Microsoft Robotics Studio-便笺服务(译文)
原文地址:https://www.codeproject.com/Articles/20393/Microsoft-Robotics-Studio-A-pad-service
原文作者:Pedro77
译文由本站 robot-v1.0 翻译
前言
Implement a pad service using CCR and DSS
使用CCR和DSS实施便签服务
介绍(Introduction)
在本文中,您将看到如何创建Microsoft Robotics(从现在开始为MR)服务以使用游戏手柄.这篇文章不是(In this article you will see how to create a Microsoft Robotics (from now MR) service to use a game pad. This article is not a) CCR(CCR) 或一个(or a) DSS(DSS) 教程,并且对这些技术有很好的了解将非常有用.在本文中,我假设您知道什么是消息,队列和服务.(tutorial, and a good knowledge in these technologies will be very useful. In this article I assume you know what messages, queues and services are.)
基本思想很简单:该服务将在每个月轮询游戏手柄设备(The base idea is quite simple: the service will poll the gamepad device every) x
毫秒.将使用托管直接输入(.NET版本)查询游戏手柄设备,并从(milliseconds. The gamepad device will be queried using managed direct input (.NET version) and will return values from) -1
至(to) 1
.因此,例如,左上角将是(. So, for example the left upper corner will be) (-1,1)
右下角将是(and the right lower corner will be) (1,-1)
.(.)
没有计时器或线程将用于实现轮询.我将仅使用消息和队列以及CCR类.(No timers or threads will be used to implement polling. I will use only messages and queues and the CCR Classes.)
背景(Background)
关于硬件的几句话((Few words about hardware () 垫(the pad) ).我使用了Logitech Dual Action游戏手柄(USB).这是一种便宜又好玩的游戏设备,精确到足以控制业余机器人.我从未经历过直接输入法,因此由于我的知识不足,我不得不(). I’ve used a Logitech Dual Action Gamepad (USB). This is a cheap and good device for gaming, precise enough to control an hobbyist robot. I never experienced Direct Input so I was forced, because of my poor knowledge, to)“硬编码”(“hard code”)代码中的数字值.我认为这些值与我的硬件严格相关,因此,如果您使用其他游戏手柄,请相应地更改它们.(numeric values inside the code. I assume that these values are strictly related to my hardware, so, if you have a different gamepad change them accordingly.) 此服务的下一版本将使用XML文件提供配置支持.(The next version of this service will have configuration support using XML files.) 为了编译此解决方案,您必须具有(In order to compile this solution, you must have the)**Microsoft.DirectX.DirectInput.dll(Microsoft.DirectX.DirectInput.dll)**文件.你可以在找到它(file. You can find it in) Directx SDK(Directx SDK) .(.)
该项目(The project)
要创建空服务,您有两种方法:从空白解决方案开始或开始使用(To create an empty service, you have two ways: start from a blank solution or start using)DssNewService.exe(DssNewService.exe).我将向您展示一种简单的方法:打开MR命令行并cd到samples目录,然后启动(. I will show you the easy way: open MR command line and cd to samples directory, then launch)**DssNewService.exe/s:Pad(DssNewService.exe /s:Pad)**这将创建一个新项目,其中包含所有需要的文件,以便拥有带有DSS服务的VS2005解决方案.该项目还具有生成代理类的生成后操作.(This will create a new project which contains all the needed files in order to have a VS2005 solution with a DSS service. The project also has post build actions to generate Proxy classes.) 创建的其他文件是(The other files created are)**Manifest.xml(Manifest.xml)**和(and the)**PadTypes.cs(PadTypes.cs)**文件. PadTypes包含此服务将使用的所有消息.在此定义服务将响应的"操作".(files. PadTypes contains all the messages this service will use. There you define the “actions” your service will respond to.) 打开解决方案并添加对(Open the solution and add reference to)Microsoft.DirectX.DirectInput.dll(Microsoft.DirectX.DirectInput.dll).加:(. Add:)
using Microsoft.DirectX.DirectInput;
上(on)Pad.cs(Pad.cs).现在,您可以使用托管直接输入.(. You are now able to use Managed Direct Input.) 该服务分为三个逻辑部分:(The service is split into three logical sections:)
- 直接输入初始化(Direct Input Init)
- 直接输入轮询(Direct Input Polling)
- 讯息通知(Message Notifications)
直接输入初始化(Direct Input Init)
//private class variable
private Device _gamepad = null;
...
//Init direct input
DeviceList devlist = Manager.GetDevices(DeviceClass.GameControl,
EnumDevicesFlags.AttachedOnly);
foreach (DeviceInstance inst in devlist)
{
Guid g = inst.InstanceGuid;
_gamepad = new Device(g);
_gamepad.SetCooperativeLevel(_form.Handle,
CooperativeLevelFlags.Background |
CooperativeLevelFlags.NonExclusive);
}
if (_gamepad != null)
{
_gamepad.SetDataFormat(DeviceDataFormat.Joystick);
_gamepad.Acquire();
}
现在我们可以使用(Now we can use) _gamepad
查询打击垫状态以搜索" Sticks"值或按钮状态.的(to query the pad status to search for Sticks values or buttons status. The) _form
仅用于获取初始化的"句柄"(is used only to get a “Handle” to init) DirectInput
.该表格可用于提供垫的图形反馈.(. This form could be use to provide graphical feedback of the pad.)
注意!(ATTENTION!)如果我在VS2005中开始调试(F5),则会收到"加载程序锁定"警告.这是通过(If I start debugging (F5) in VS2005, I get a “Loader Lock” warning. This is done by) 托管调试助手(MDA)(Managed debugging assistants (MDAs)) .因此,您可以按照本文所述禁用助手,也可以稍后运行并附加到进程进行调试(CTRL + ALT + P).(. So you can disable assistants as the article describes or you run and attach to process later for debugging (CTRL + ALT + P).)
直接输入轮询(Direct Input Polling)
填充轮询分为两个"块".第一个基于"计时器":每次滴答时,都会执行游戏手柄读取,并且数据会立即发送到队列.仲裁器在队列上被激活:匿名委托处理消息,并最终将新的"事件"通知主端口.(Pad polling is split in two “blocks”. The first one is based on a “timer”: on every tick a gamepad read is performed and data is immediately sent to a queue. An Arbiter is activated on the queue: an anonymous delegate process messages and eventually notifies new “events” to the main port.) 使用此代码段即可实现计时器(从(The timer is achieved using this snippet (freely taken from) 机器人实例(robotics examples) ).().)
//the timer port
private Port<DateTime> _timerPort = null;
...
_timerPort = new Port<DateTime>();
...
_timerPort.Post(DateTime.Now);
Activate(Arbiter.Receive(true, _timerPort,
delegate(DateTime sign)
{
Activate(//every 75 ms ...
Arbiter.Receive(false, TimeoutPort(75),
delegate(DateTime time)
{
//poll the gamepad device and enqueue the data read
if (_gamepad != null)
{
// ... poll the pad
JoystickState jstate = default(JoystickState);
_gamepad.Poll();
jstate = _gamepad.CurrentJoystickState;
_joyReads.Post(jstate);
}
_timerPort.Post(time);
}
)
);
}
));
另一位仲裁员在(Another arbiter is active on) _joyReads
:(:)
Activate(
Arbiter.Receive<JoystickState>(true, _joyReads,
delegate(JoystickState jsta)
{
//jsta analysis in order to send external notifications
})
);
而已.填充轮询几乎完成.注释的代码读取当前的摇杆(L和R)值,并在范围内对其进行归一化(That’s it. Pad polling is almost complete. The commented code reads current sticks (L and R) values and normalize them in range) (-1,1)
.在省略的代码内,执行的感兴趣的"服务"操作与此代码段相似.(. Inside the omitted code, the interested “service” actions performed are similar to this snippet.)
RightStickUpdate actR = new RightStickUpdate();
actR.Body.Stick.StickValueX = _state.RightStick.StickValueX;
actR.Body.Stick.StickValueY = _state.RightStick.StickValueY;
LogInfo("RightStickUpdate " + actR.Body.Stick.StickValueX,
actR.Body.Stick.StickValueY);
_mainPort.Post(actR);
RightStickUpdate
是在中定义的类(is a class defined in)**PadType.cs(PadType.cs)**文件.(file.)
public class RightStickUpdate :
Update<StickUpdateResponseRight, PortSet<DefaultUpdateResponseType, Fault>>
{
private StickStatus _stick;
[DataMember]
public StickStatus StickStatus
{
get { return _stick; }
set { _stick = value; }
}
public RightStickUpdate()
: base(new StickUpdateResponseRight())
{
_stick = base.Body.Stick;
}
}
最后一步是在消息处理程序方法内部,例如:(The last step is inside the messages handler methods, for example:)
[ServiceHandler(ServiceHandlerBehavior.Exclusive)]
public IEnumerator<ITask> RightStickUpdateHandler(RightStickUpdate rsUpd)
{
rsUpd.ResponsePort.Post(DefaultUpdateResponseType.Instance);
//notify it
SendNotification(_submgrPort, rsUpd);
yield break;
}
在响应端口上发布并发送通知.服务流程现已完成.在解决方案内部,还定义了其他消息以完全处理操纵杆和按钮.(Post on response port and send notification. The service flow is now complete. Inside the solution other messages are defined to fully handle sticks and buttons.)
图形用户界面(GUI)
即将开发GUI,以提供有关焊盘状态的反馈.要在服务"内部"显示表单,请使用此代码段(实际上在源文件中已注释).的(A GUI will be developed soon to give feedback on pad state. To show a form “inside” a service, use this snippet (actually commented in the source files). The) PadInfoForm
完全是空的.(is totally empty.)
using Microsoft.Ccr.Adapters.WinForms;
...
//Create Form
PadInfoForm _form = new PadInfoForm();
WinFormsServicePort.Post(new RunForm(
delegate()
{
return _form;
}
));
下一个改进将是GUI.如果您有任何意见和建议,请发表!(The next improvement will be a GUI. If you have comments and suggestions, please post!)
历史(History)
- 2007年9月:第一版(September 2007: First release)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
C# C#2.0 WinXP Vista smartphone embedded .NET2.0 Visual-Studio VS2005 Dev 新闻 翻译