Orchestration Services in Robotics


Orchestration services

Orchestration is a type of automated system arrangement, coordination and management of Complex computer systems and middleware as well. Middleware is actually software components and their applications. It allows interaction among number of processes which are running either on different machines. It is found in the middle between software working on different operating systems. It connects two applications and allows transfer of data between them. It enables users to access data of one database through another. Web Services Orchestration (WSO) is a process of collaborating web services, first interactions are done at different levels and then on the basis of those interactions web services are collaborated on those pre-defined patterns. This WSO is executed via 'orchestration scripts'. In this article we will use C# to create reusable orchestration services. We are using Microsoft Robotics Developer Studio (RDS),It provides a reusable design for writing services It actually allows us to write a service once to a common hardware specification and then we can use that service across different platforms.

We just have to right click orchestration and select start

Requirements:

Hardware:

As we have discussions about Hardware components in our article, we need a robot with microcontroller and sensor. Here we can use Infrared sensors. We require to keep sensors on front and rear part. We also require motors two motors in a two wheeled differential drive configuration. Do all the necessary connections.

Software:

     We can use Microsoft visual for this case

  • Microsoft Visual C# Express Edition.
  • Microsoft Visual Studio Standard, Professional, or Team Edition.

Others?

Web Browser, We can use any web browser for this application.

Steps: First of all, we will check out an existing service installed in samples\Robotics Tutorials\Tutorial(name)\CSharp.Load RoboticsTutorial.cjproj file. The service uses common definitions in RoboticsCommon.Proxy.dll.The Dll exists as a project reference.

C#

using contactsensor = Microsoft.Robotics.Services.ContactSensor.Proxy;

using drive = Microsoft.Robotics.Services.Drive.Proxy;

Using motor = Microsoft.Robotics.Services.Motor.Proxy;

Drive command to turn and move

As its name suggest, the Turn and move method does the following steps:

1.    Reverse direction and move for 1500ms.

2.    Apply equal magnitude, but opposite polarity, power to the two motors in each wheel of the drive service.
This rotates the robot.

3.    Apply equal power to both motors for a random period of time to move the robot.

C#

Random _randomGen = new Random();
// <summary>
///create motion in robot
/// </summary>
///
<param ="polarity">1 for going forward, -1 for going backwards</param>
///
<returns></returns>
IEnumerator<ITask> BackUpTurnAndMove(double polarity)
{
// First backup a little
yield return Arbiter.Receive(false,
StartMove(0.4*polarity),
delegate
(bool result) { });
// wait
yield return Arbiter.Receive(false, TimeoutPort(1500), delegate(DateTime t) { });
// now Turn
yield return Arbiter.Receive(false,
StartTurn(),
delegate
(bool result) { });
// wait
yield return Arbiter.Receive(false, TimeoutPort(1500), delegate(DateTime t) { });
// now reverse direction and keep moving straight
yield return Arbiter.Receive(false,
StartMove(_randomGen.NextDouble()*polarity),
delegate
(bool result) { });
// done
yield break;
}
Port<bool> StartTurn()
{
Port<bool> result = new Port<bool>()
// start a turn
SpawnIterator<Port<bool>>(result, RandomTurn);
return
result;
}

Port<bool> StartMove(double powerLevel)
{
Port<bool> result = new Port<bool>();
// start movement
SpawnIterator<Port<bool>, double>(result, powerLevel, MoveStraight);
return
result;
}
IEnumerator<ITask> RandomTurn(Port<bool> done)
{
//motors commands are used to take turns, reverse polarity for right-left
double randomPower = _randomGen.NextDouble();
drive.SetDrivePowerRequest setPower = new drive.SetDrivePowerRequest(randomPower, -randomPower);
bool
success = false;
yield
return
Arbiter.Choice(
_drivePort.SetDrivePower(setPower),
delegate(DefaultUpdateResponseType rsp) { success = true; },
delegate
(W3C.Soap.Fault failure)
{
//if error, then report
// try to do the same step even it results in failure
LogError("Failed setting drive power");
});
done.Post(success);
yield
break;
}
IEnumerator<ITask> MoveStraight(Port<bool> done, double powerLevel)
{
drive.SetDrivePowerRequest setPower = new drive.SetDrivePowerRequest(powerLevel, powerLevel);
yield
return
Arbiter.Choice(
_drivePort.SetDrivePower(setPower),
delegate
(DefaultUpdateResponseType success) { done.Post(true); },
delegate
(W3C.Soap.Fault failure)
{
//If error, then report          
//  try to do the next step even if it results in failure
LogError("Failed setting drive power");
done.Post(false);
});
}