Robotics Tutorial 3 (VPL) - Creating Reusable Orchestration Services

Glossary Item Box

Microsoft Robotics Developer Studio Send feedback on this topic

Robotics Tutorial 3 (VPL) - Creating Reusable Orchestration Services

Microsoft Robotics Developer Studio (RDS) provides a re-usable design for writing services. This design allows you to write a service once to a common hardware specification and then use that service across a variety of hardware robotics platforms.

This tutorial teaches you how to create a custom activity that partners with abstract, base definitions of hardware services. Then, based on a configuration file (a manifest), that service binds at runtime to a specific implementation of these hardware services. The tutorial implements a very basic wandering behavior.

If a bumper is pressed, your robot backs up for a short distance, turns randomly for a brief amount of time, and then goes straight at a random velocity.

This tutorial can also be used in a Simulation without requiring any robotics hardware.

This very primitive behavior will result in the wheeled robot bumping into things and turning. For a more intelligent (and more advanced orchestration service) please review Robotics Tutorial 5 (C#) - Using Advanced Services and the Explorer Service.

This tutorial is provided in the Microsoft Visual Programming Language (VPL) language. You can find the project files for this tutorial at the following location under the Microsoft Robotics Developer Studio installation folder:

Sample location

Samples\RoboticsTutorials\Tutorial3\mvpl

This tutorial teaches you how to:

  • Create a Custom Activity using Generic Services
  • Orchestrate the Custom Activity
  • Select a Manifest for Your Hardware
  • Run Your Application

See Also:

  • Getting Started

Prerequisites

Hardware

You need a robot with a contact sensor. The sensor can also be a distance detection device (like sonar or an infrared sensor) that provides a simple binary signal when a particular threshold is detected. Configure your contact sensor so that one is at the front and the other is at the rear.

This tutorial also requires two motors in a two-wheeled differential drive configuration.

Connect the sensors and motors to your robotic platform following the normal conventions for the hardware you are using.

To determine if support is included in RDS for your robot and to setup your hardware, see Setting Up Your Hardware. You may be able to apply this tutorial for other robots that provide similar services (or create your own services by performing the Service Tutorials included in Robotics Developer Studio). Setting up Your Hardware may also provide you with any recommended guidelines for setting up your PC to communicate with your robot.

Software

This tutorial is designed for use with Microsoft Visual Programming Language.

Microsoft Visual Programming Language (VPL) is an application development environment designed on a graphical data-flow programming model rather than control flow typically found in conventional programming. Rather than series of imperative commands sequentially executed, a data-flow program is more like a series of workers on an assembly line who do their assigned task as the materials arrive. As a result, VPL is well suited to programming a variety of concurrent or distributed processing scenarios.

VPL is targeted for beginning programmers with a basic understanding of concepts like variables and logic. However, VPL is not limited to novices. The compositional nature of the programming language may appeal to more advanced programmers for rapid prototyping or code development. In addition, while its toolbox is tailored developing robot applications, the underlying architecture can be applied to other applications. As a result, VPL may appeal to a wide audience of users including students, enthusiasts/hobbyists, as well as possibly web developers and professional programmers.

You will also need Microsoft Internet Explorer or another conventional web browser.

Getting Started

Begin by opening the VPL development environment and creating a new project by selecting New from the File menu.

Step 1: Create a Custom Activity using Generic Services

RDS comes with a large number of services that you can use to build your programs. Sometimes, however, they don't have the specific commands you are looking for. For this tutorial you need a drive activity that has commands for backup, turn randomly, and drive straight with a random speed. Unfortunately, there is no such activity. You can build one yourself by using the Generic Differential Drive. (Also see VPL Tutorial 3 - Create Your Own Activity).

Create a new activity by dragging an Activity from the Basic Activities toolbox into your diagram. You should always give your activities meaningful names. The new activity should already be selected (as indicated by the highlighting around its border). If not, click on it to select it. Go to the Properties toolbox and change its Name to RandomDrive. Do the same for the Friendly Name. The new activity should look like the following:

Figure 1

Figure 1 - New activity

At this stage it is a good idea to save your diagram and give it a name by selecting Save from the File menu. Notice in the title bar of the screenshot above the name of the diagram is "Unnamed" and there is an asterisk beside it which indicates that the diagram has been modified but not saved. Even if you are editing the VPL program that came with RDS, you should save it under a diferent name by usng Save As so that you have the original to refer back to if necessary.

Open the new activity to see its implementation by double-clicking on its block or choosing Open from the context menu. This opens a new page displaying the diagrams contained within the activity and a new tab appears at the top of the diagram area in VPL. (A new activity will not contain any data-flows, so the new page will be empty). Activities have a separate diagram for each action defined in the activity. You can choose the displayed action with the drop-down box at the top of the page.

Figure 2

Figure 2 - New activity page

A new activity initially has two actions called Start and Action. The Start action runs once immediately after the activity starts. You don't need it in this tutorial so you can simply ignore it. The second action, named Action, can handle input requests from other diagrams in the same way you as you used the operations of a service in the previous tutorials. Notice at the left and right-hand edges of the activity page there are pins similar to those you have already seen on activity blocks. These are the internal connection points for the activity so that it can interact with other activities.

An activity can have more than these two actions. To add new actions to the activity, use the Actions and Notifications command in the Edit menu or click the icon next to the action selector drop-down at top of the page.

In the Actions and Notifications dialog, change the name from Action to Backup. Add two more actions by clicking the Add button below the Actions list twice. Set the names of these new actions to Turn and Drive.

Figure 3

Figure 3 - Actions and Notifications dialog

When you implement these actions, you have to know which direction the robot is currently going so that you can reverse it. The direction can be sent as an Input value to the action. For each action, add a new Input value by clicking on the Add button below the list of Input values. Change the Input's name to Polarity and its type to double. (You will later use -1.0 to indicate reverse and 1.0 to indicate forward.) Click OK when you are done adding the Input to all three actions.

Figure 4

Figure 4 - Actions dialog with Input

This tutorial explains in detail how to implement the Turn activity, the most complex of the three. Drive and Backup are simplified versions of Turn.

On the action selector drop-down, select the Turn action. A screen opens with connectors on the left and right side borders. The connectors represent the input to the action (on the left) and the action's output and notifications (on the right).

The turn speed should be random, so you need to come up with a random value. The easiest way to do this is by using the Math Functions. Add a Math Functions block to your diagram and connect the Turn action's input (on the left-hand border) to the input of the Math Functions block. On the connections dialog, choose Random in the To list. Random does not take any input values so there is nothing to set up for Data Connections. This connection from the Turn action's input is just used for control flow, not to transfer any data.

Random returns a value between 0.0 and 1.0. While 1.0 is also the maximum value to set the motor speed on the generic drive, in the interest of public safety, you should consider scaling it down a bit. You also want to make sure that the value is not too close to zero since the robot might not turn at all.

Connect the output of the Math Functions block to a new Calculate and choose Random - Success in the From in the Connections Dialog.

Figure 5

Figure 5 - Create a random number

The resulting random value (after the calculation) will be between 0.25 and 0.75. Use this value to calculate the motor powers to set on the differential drive. In order to take the current direction in which the robot is traveling into account, you need to extract the Polarity value from the input using a Calculate and combine it with the random value using a Join. The Join combines the two values into a single message, but it does not send the message until both of the incoming values have been received.

Figure 6

Figure 6 - Joining Random and Polarity

In order to make the robot turn, the wheels have to rotate in different directions. Use two Calculate blocks to calculate the power values for the left wheel and the right wheel and combine the values using a Join, calling the values Left and Right.

Figure 7

Figure 7 - Calculating left and right powers

Add a Generic Differential Drive (GDD) service to your Turn action and connect it to the Join. Choose the SetDrivePower command from the To list. In the Data Connections dialog. Select Left for LeftWheelPower and Right for RightWheelPower. Note that in the following screenshot the GDD block has been reversed by selecting "Flip Connections" from its context menu. This is for illustration purposes.

Figure 8

Figure 8 - Set Drive Power

Now you've got your robot turning. You want to make sure that it can actually turn for some time so that it really changes direction. A simple way of achieving this is by waiting for a brief period of time before doing something else. Add a new Timer service. Add a Data block, setting int as its type and connect it to the Timer. Select Wait in the Connections Dialog's To list. In the Data Connections dialog, set the value to Interval. Interval is the amount of time to wait in milliseconds. Enter a value that is appropriate for the speed of your robot in the Data block.

Connect the output of the drive's SetDrivePower operation to the Data block and choose SetDrivePower - Success from the From list. Connect the Timer to the Result output of the Turn action. The Turn action has no output values. However, you can still send a result message indicating "I'm done" by connecting the output of the Timer to the action's Result pin, which makes sure that this message is not sent before the robot has finished turning.

Figure 9

Figure 9 - Wait for a while

The completed action should look like the following:

Figure 10

Figure 10 - Completed Turn Handler

You can build the Drive and Backup actions based on Turn. When you add the GenericDifferentialDrive to Drive and Backup, make sure to select the same drive and do not create a new one when you are asked. All GenericDifferentialDrive blocks in all actions must have identical names. Alternatively, you can just copy the GenericDifferentialDrive block from the Turn action. By using the generic drive, you can use your RandomDrive with many different platforms and even simulation without having to change it.

Figure 11

Figure 11 - Add Activity Dialog

The Backup action is similar to Turn except it uses fixed values instead of random and uses the same power for both wheels.

Figure 12

Figure 12 - Backup Action

The Drive uses the same random value for both wheels and doesn't wait. This allows a change in direction immediately after starting to go forward again.

Figure 13

Figure 13 - Drive Action

Step 2: Orchestrate the Custom Activity

The RandomDrive activity can now Backup, Turn randomly, and Drive forward with a random speed. Use this activity to build the wanderer program.

Go back to the main diagram of your project.

Add a Generic Contact Sensor (i.e. a bumper) service to the diagram. By using the generic drive, you can use your wander diagram with many different platforms. Whenever the bumper is pressed, the following actions occur:

  • Backup
  • Turn
  • Drive

Wandering is now simply a matter of connecting up the RandomDrive correctly.

Select Variables... from the Edit menu. In the dialog, define a new variable for the main diagram called Polarity of type double. This step is similar to how you defined a variable with the same name in the various actions in RandomDrive. Use a new Data block and another Variable block to initialize the variable with 1.0 (forward).

Add a new If and connect it to the contact sensor's notifications (drag the round connector on the GenericContactSensor to the If). Select Update in the From list.

In the If condition, type Pressed. You now need to know what the current direction of the robot is and change it. Copy the Variable block for Polarity and connect the output of the If to the Variable block. Select GetValue from the Connections dialog. The diagram should look as follows:

Figure 14

Figure 14 - Add the Polarity variable

Now you have the current direction and can use it to back up and turn. Connect the Variable block to the RandomDrive block. Select the Backup action in the To of the connection dialog. In the Data Connections dialog select, Polarity for the Polarity input value.

After Backup has completed, you can Turn. Because you also need the new Polarity value, you have to combine (add a Join) the result of Backup with the result of the Calculate that calculates the new direction (by changing the sign of the old direction). Make a copy of RandomDrive and connect the Join block to it. In the Connections dialog, select Turn from the To list. In the Data Connections dialog, select Polarity for the Polarity input value.

Figure 15

Figure 15 - Backup and Turn

Add another Join and send a Drive message to the RandomDrive after the Turn. This is similar to what you have just done. Finally, you need to remember the new direction in the Polarity variable so that you can use it the next time the bumper is pressed. Add a new Variable block, select Polarity, and connect the Calculate to it. Select SetVariable in the Connections dialog.

When you're finished, your diagram should look like the following.

Figure 16

Figure 16 - Completed Wander Diagram

Step 3: Select a Manifest for Your Hardware

Before you run your program, you need to set the manifests for the Contact Sensor and the Differential Drive services. Click the context pop-up menus for each of these services and choose the Manifest command. In the dialog box which opens, choose the manifest for your robot. If you don't have a robot that's supported you can try a simulated mobile robot manifest.

Step 4: Run Your Application

Run your application by selecting the Run command from the Run menu or by pressing F5. You can let the robot wander around until it bumps into an obstacle. It should back up, turn and then drive off in a new direction. If you want to test it, you can hit the bumper rather than waiting for it to bump into something.

Summary

In this tutorial, you learned how to:

  • Create a Custom Activity using Generic Services
  • Orchestrate the Custom Activity
  • Select a Manifest for Your Hardware
  • Run Your Application

 

 

© 2012 Microsoft Corporation. All Rights Reserved.