Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Задани на лабораторные работы. ПРК / Professional Microsoft Robotics Developer Studio

.pdf
Скачиваний:
126
Добавлен:
20.04.2015
Размер:
16.82 Mб
Скачать

www.it-ebooks.info

Chapter 3: Decentralized Software Services (DSS)

Execution Context

The context of a service includes all of its partners. These are other services that it relies on to do its job. The obvious examples for a robot are the motors that drive the wheels, infrared sensors, and so on. A service can have as many partners as it likes, and the partnerships can be dynamic.

By design, partners do not have to be on the same computer. Each computer runs an instance (or possibly multiple instances) of a DSS node. A service directory is maintained in each DSS node. As you have already seen, one of the possible operations on a service is a lookup.

In most cases, partnerships last for the duration of the service execution. Therefore, they are often established declaratively in the code (using attributes). However, MRDS has a concept of generic contracts. These types of contracts specify the operations that a conforming service must support. At runtime, any service that complies with the generic contract can be used as a partner. The association between the actual service and the generic service is done using a manifest, which is an XML file that uses a schema defined by Microsoft.

A common example is the generic differential drive service for two-wheeled robots. The manifest can connect a service to the drive on a Boe-Bot, or a LEGO NXT Tribot, or a Stinger, and so on, and the service should have no idea what type of robot it is talking to.

One case where partnerships are established on demand is when you use the Dashboard (which is described in Chapter 4). In order to do this, the Dashboard must query the service directory to find services that implement generic contracts that it understands, such as the differential drive, game controller, laser range finder, webcam, and so on. The execution context of the Dashboard, therefore, changes over time.

The following manifest starts a Boe-Bot and the Dashboard. It runs the BASICStamp2 service, which is the “brick” or “brain” on the robot; the BSDrive service, which controls the wheels; and the Dashboard:

<?xml version=”1.0” encoding=”utf-8”?> <Manifest

xmlns=”http://schemas.microsoft.com/xw/2004/10/manifest.html”

xmlns:dssp=”http://schemas.microsoft.com/xw/2004/10/dssp.html”

>

<CreateServiceList>

<!--Start BasicStamp2 Brick --> <ServiceRecordType>

<dssp:Contract>http://schemas.microsoft.com/robotics/2007/06/basicstamp2.html

</dssp:Contract>

<dssp:PartnerList>

<!--Initial BasicStamp2 config file --> <dssp:Partner>

<dssp:Service>Parallax.BoeBot.Config.xml</dssp:Service>

<dssp:Name>dssp:StateService</dssp:Name>

</dssp:Partner>

</dssp:PartnerList>

</ServiceRecordType>

<!--Start the BoeBot drive service-->

(continued)

93

www.it-ebooks.info

Part I: Robotics Developer Studio Fundamentals

(continued)

<ServiceRecordType>

<dssp:Contract>http://schemas.microsoft.com/robotics/2007/06/bsdrive.html

</dssp:Contract>

<dssp:PartnerList>

<!--Initial Drive Configuration File --> <dssp:Partner>

<dssp:Service>Parallax.BoeBot.Drive.Config.xml</dssp:Service>

<dssp:Name>dssp:StateService</dssp:Name>

</dssp:Partner>

</dssp:PartnerList>

</ServiceRecordType>

<!-- Dashboard --> <ServiceRecordType>

<dssp:Contract>http://schemas.microsoft.com/robotics/2006/10/dashboard.html

</dssp:Contract>

</ServiceRecordType>

</CreateServiceList>

</Manifest>

You can clearly see each of the services listed inside a ServiceRecordType. The BASICStamp2 and BSDrive also partner with the StateService, which is responsible for loading the initial state from the specified config file.

Don’t worry about manifests at this stage. MRDS includes a Manifest Editor that makes creating them relatively easy. This is discussed later in the chapter.

DSSP Service Operations

The DSSP service model defines many operation classes. Luckily, most of these you will never use in an MRDS service. (If you are interested, you can read the full DSSP specification, available at http:// download.microsoft.com/download/5/6/B/56B49917-65E8-494A-BB8C-3D49850DAAC1/DSSP.pdf).

The full list of DSSP operations is shown in the following table. You do not need to know all of these operations, but they are included here for completeness.

Operation

Description

 

 

Create

Creates a new service

Delete

Deletes (part of) service state

Drop

Terminates a service (actually, requests the service to terminate itself)

Get

Retrieves a copy of the service state

Insert

Adds new information to the service state

Lookup

Retrieves information about the service and its context

 

 

94

 

 

www.it-ebooks.info

 

 

Chapter 3: Decentralized Software Services (DSS)

 

 

 

 

 

 

Operation

Description

 

 

 

 

 

 

Query

Similar to Get but with additional parameters to allow structured queries.

 

 

 

(Returns a subset of the state.)

 

 

Replace

Replaces the entire service state

 

 

Subscribe

Requests notification of all state changes

 

 

Submit

Special case of an Update that does not necessarily change state (typically used

 

 

 

with Web Forms)

 

 

Update

Retrieves information about the service and its context

 

 

Upsert

Performs an Update if the state information exists, otherwise an Insert

 

 

 

 

 

The only mandatory operation according to the DSSP specification is Lookup. However, for practical reasons, MRDS always creates services with Lookup, Drop, and Get. A service that only implemented Lookup would be pretty useless.

The DSS runtime provides a wrapper, CreateService, for the Create operation. Lookup operations are a little more complicated, but can be handled by requests to the Directory service.

All of the operations are based on the generic DsspOperation class:

public class DsspOperation<TBody, TResponse>

To define your service operations, you subclass one of the standard DSSP operations and supply your own body type (which is the request) and a PortSet for the response.

An example will help to clarify this. The Hemisson services in Chapter 16 have a request to read the IR sensors. It is defined as follows:

[DisplayName(“GetSensors”)]

[Description(“Gets the state of the infrared sensors”)]

public class QueryInfraRed : Query<SensorsRequest, PortSet<Sensors, Fault>>

{

}

[Description(“Requests sensor data”)] [DataContract]

public class SensorsRequest

{

}

This new operation type, QueryInfraRed, is based on the Query class because it only retrieves part of the state. When a new instance is created, the Body field contains a variable of type SensorsRequest, and the ResponsePort field is a PortSet that returns either a Sensors object or a SOAP Fault. (The Sensors class is not shown here. It contains all of the IR sensor values.)

95

www.it-ebooks.info

Part I: Robotics Developer Studio Fundamentals

A key point to note is that the request type must be unique among all of the types in the main operations PortSet. If you tried to implement requests using an int for several of them, only the first one in the PortSet would ever get any messages.

This new class must be added to the main operations port for the Hemisson services, and then a handler can be written as follows:

///<summary>

///QueryInfraRed Handler

///</summary>

///<param name=”query”></param>

///<returns></returns> [ServiceHandler(ServiceHandlerBehavior.Concurrent)]

public virtual IEnumerator<ITask> QueryInfraRedHandler(QueryInfraRed query)

{

query.ResponsePort.Post(_state.Sensors); yield break;

}

Notice that this handler returns only the Sensors portion of the state. How this sensor information is updated is irrelevant here. It is the responsibility of the service to obtain this data from the robot and make it available.

The [ServiceHandler]attribute flags this method as being a handler, and the QueryInfraRed parameter indicates what type of operation it handles. The attribute also specifies which interleave group the handler should be in.

This behavior is in the Concurrent interleave group. This means that it is allowed to execute in parallel with other Concurrent handlers. However, it cannot execute while an Exclusive handler is running.

The third group of handlers are TearDown handlers. Usually this group only contains the Drop handler. TearDown handlers are not only exclusive; they also prevent further execution of any other

handlers. The last thing that a service must do when it receives a Drop request is to post back a response.

The QueryInfraRed example shows a request that basically has an empty body and returns some information. The opposite is a request that sends information but does not expect any information in the response. The PlayTone operation from the Boe-Bot (see Chapter 14) is an example:

[DisplayName(“PlayTone”)]

[Description(“Plays a tone on the speaker on the Boe-Bot.”)]

public class PlayTone : Update<Tone, PortSet<DefaultUpdateResponseType, Fault>>

{

}

The PlayTone operation sends a Tone object as the request body, but it only receives a DefaultUpdateResponseType to indicate success (or a Fault for failure). There are pre-defined classes for the default responses to most of the operation classes so that you do not have to bother defining response types for all of your operations.

96

www.it-ebooks.info

Chapter 3: Decentralized Software Services (DSS)

The Tone class is marked as part of the data contract. It also specifies two data members as the parameters for a constructor, Frequency and Duration:

[Description(“Sound a Tone on the Speaker.”)] [DataContract]

public class Tone

{

// Parameters

private int _frequency; private int _duration;

[DataMember, DataMemberConstructor(Order = 1)] [Description(“Frequency in Hz (rounded to nearest 50Hz).”)] public int Frequency

{

get { return this._frequency; } set { this._frequency = value; }

}

[DataMember, DataMemberConstructor(Order = 2)] [Description(“Duration in Milliseconds (rounded to nearest 50ms).”)] public int Duration

{

get { return this._duration; } set { this._duration = value; }

}

}

As a convenience, the Proxy generator (discussed later in the section “Proxy Assemblies”) will create appropriate helper methods on the proxy operations port so that you can write the following command (assuming _stampPort is already set up as the operations port):

_stampPort.PlayTone(3000, 500);

This constructs a new Tone object and sends it to the Boe-Bot.

Because the PlayTone operation returns a PortSet, you can also use it in a Choice:

yield return Arbiter.Choice(

_stampPort.PlayTone(3000, 500), delegate(DefaultUpdateResponseType d) { },

delegate(Fault f)

{

Console.WriteLine(“Play Tone failed: “ + f.Reason);

}

);

This has the added benefit that execution will not continue until the PlayTone request has been completed, and of course it is also defensive programming because it explicitly flags errors.

97

www.it-ebooks.info

Part I: Robotics Developer Studio Fundamentals

A Note About Console.WriteLine

Throughout this chapter and the previous one, you have used Console.WriteLine statements to output information to the console (the MRDS Command Prompt window). This is okay in simple examples, but it should not be used in real services.

You should use LogInfo, LogWarning, LogError, or LogVerbose to output diagnostic information and error messages. These messages can be read using a web browser, as you will see shortly. If you want the output to still appear on the console, you can specify where it should be directed as follows:

LogInfo(LogGroups.Console, “some message”);

Log messages begin with an asterisk and have a timestamp and the service URI appended, which makes it easy to identify where they came from (see Figure 3-4 for some examples). However, this additional information clutters up the output, so for the purposes of illustration, Console.WriteLine is used in the examples. Make a mental note that this is not best practice.

Generic Contracts

A generic contract is similar to an abstract class, but MRDS does not implement class inheritance in the usual sense. Generic contracts have no implementation of their own. They consist solely of the type definitions required for the contract identifier, the state, and the main operations port.

To implement a generic service, you must build a service based on the generic contract. This can be done most easily using the /alt qualifier to DssNewService to specify the generic contract that should be used. This is covered in more detail in Chapter 4.

The implementation service has two operations ports: one for the new service itself and one that receives requests based on the generic contract. In your source code for the new service, you must implement handlers for all of the operations defined in the generic service contract. There is no requirement to add more handlers to the new service (apart from Lookup, Drop, and Get, which all services have). The simplest implementation, therefore, consists only of handlers for the generic operations, in which case you do not need your own operations port.

The reason for defining generic contracts is to try to make MRDS services hardware-independent in the same way that device drivers hide hardware details from an operating system.

Running a DSS Node

A program called DssHost.exe is responsible for implementing the run-time environment for MRDS. In the text, references to DSS usually mean the environment created by DssHost. In Figure 3-1, the DSS nodes are instances of DssHost running on a Windows-based computer (or computers). The online documentation contains a full description of DssHost. You can also get abbreviated help from DssHost itself, as described in this section, which explains how to start DssHost and get information from it.

98

www.it-ebooks.info

Chapter 3: Decentralized Software Services (DSS)

DssHost implements a web server so that you can interrogate DSS and running services using a web browser. This is a novel approach that means you can examine and manipulate the state of services running in a DSS node across the network without installing any special client software to do it.

When you start a DSS node, several services are started automatically. You will explore most of these services in this chapter. They include the following:

Console Output: Captures and filters informational and error messages

Constructor: Creates new service instances

Control Panel: Provides an interface to start and stop services manually

Manifest Loader: Interprets manifests to set up the services comprising applications

Mount Service: Provides access to the local file system (only under the MRDS folder)

Embedded Resource Manager: Exposes icons, bitmaps, XSLT files, and other resources

Security Manager: Manages the security on the DSS node

Service Directory: Maintains a list of available services on the DSS node

State Partner Service: Reads configuration files when services start

Directory Structure of a DSS Node

The layout of a DSS node is as follows:

Root directory (or Mount point)

Bin

Store

Logs

Media

Styles

Transforms

When you deploy the MRDS runtime to another computer, this is the minimal directory structure that is created. If you have a full installation of MRDS on your computer, then there are many more directories but they are not required to run MRDS.

In a web browser, you can go to the Service Directory (as explained below) and click on the mountpoint service to see the local path where MRDS is installed, which is referred to as the root directory or the mount point. The mountpoint service can be used in your code to access local files, but it only allows you to access files below the MRDS root directory.

You can find out where your local DSS node is in your C# code using the LayoutPaths static class, as shown in this example:

string logdir = LayoutPaths.RootDir + LayoutPaths.LogDir;

This will give you the full path to the Logs directory if you want to write your own log file.

99

www.it-ebooks.info

Part I: Robotics Developer Studio Fundamentals

File I/O operations are synchronous — that is, they block the calling thread. Therefore, you should not usually perform file I/O directly unless you know that the operations are very quick. For long operations, you might need to create a separate thread.

Starting DssHost

Open an MRDS Command Prompt window by clicking Start All Programs Microsoft Robotics Studio (1.5) Command Prompt. Enter the following command (bold text) to see all of the available command-line options:

C:\Microsoft Robotics Studio (1.5)>DssHost /?

Now start DssHost on its own (with no services) using the following command:

C:\Microsoft Robotics Studio (1.5)>DssHost /p:50000 /t:50001

The output from DssHost should look like Figure 3-4, which shows that the Directory and Constructor services started, but no manifest was supplied (so nothing else started).

Figure 3-4

Running MRDS Commands

In case you haven’t realized it yet, you must run an MRDS command prompt, not a normal MS-DOS command prompt. This is necessary to establish the correct operating environment.

All MRDS tools accept parameters on the command line. You can use either a forward slash (/) or a hyphen (-) to introduce a parameter, and even mix them in the same command.

In most cases, the names of commands and the parameters are not case-sensitive.

However, it looks better in print to use mixed case.

100

www.it-ebooks.info

Chapter 3: Decentralized Software Services (DSS)

Parameters have a full name, such as port, and an abbreviation, which in many cases is a single letter, such as p (for port).

In addition, most commands allow you to place command-line parameters into

an options file. This is a text file that contains one parameter per line. You specify an options file on the command line using an at sign (@), as in the following example:

DssHost @myoptions.txt

Options files are useful to avoid exceeding the maximum command-line length or when you have a lot of parameters and don’t want to retype them repeatedly.

DssHost requires you to specify at least the port parameter (abbreviated to /p). In the example in Figure 3-4, the tcpport is also specified with /t. At first glance this is a little confusing. The “port” numbers you give to DssHost have nothing to do with CCR ports, and why do you need two ports?

The port parameter supplies what might more appropriately be called the HTTP port, and the tcpport parameter is the SOAP port. DssHost includes a web server that can be used to examine and control services. This web server uses the port parameter. In addition, a service receives requests (SOAP messages) through its service port, which is the tcpport parameter.

There is nothing magical about the numbers 50000 and 50001 other than the fact that they are above the range of “well-known” TCP/IP ports. In fact, in the early days of MRDS, the documentation used 40000 and 40001 in many cases.

Exploring the DSS Web Pages

Once DssHost is running, start up a web browser and enter the following URL in the address bar: http://localhost:50000.

Because you will make frequent use of a web browser to examine services, it is a good idea to save a shortcut (or favorite) for this web page once it is displayed. Notice that the port number in the URL is the (HTTP) port that you specified on the command line when you started DssHost.

101

www.it-ebooks.info

Part I: Robotics Developer Studio Fundamentals

You should see something like what is shown in Figure 3-5. Notice that there are several options in the menu at the left-hand side of the window. Each of these options is explained briefly below. Try them all out for yourself. You can investigate the Developer Resources and About Microsoft Robotics Studio sections of the menu on your own.

Figure 3-5

The Control Panel

The Control Panel displays all of the available services. When you select the Control Panel, it might take a little while before anything is displayed because it initiates a refresh of the directory cache. Eventually, the Control Panel displays a list of all the available services. You can manually start services from this list.

You can narrow down the list of services by typing in a search string. Figure 3-6 shows the results of entering “cam,” which indicates all services with “cam” in their name or description, which are obviously cameras.

102