You are currently browsing the category archive for the ‘Microsoft Robotics Studio’ category.

Toaster Device Sample

This sample provides a step by step guidance on how to integrate code between the Microsoft Windows Vista DDK and Microsoft Robotics Studio using C++/CLI programming language.

This tutorial is provided in the language. You can find the project files for this tutorial at the following location under the Microsoft Robotics Studio installation folder:

Sample location
 Samples\Technologies\Interop\ToasterList

Here are the steps we have to do:

Prerequisites

Software

This tutorial requires the Windows Vista DDK also called WDK, which is available online

The actual work with the WDK is outside the scope of this tutorial, instead we are going to take an existing part of the Toaster sample from WDK and turn it into a Microsoft Robotics Studio DSS service.

The Toaster sample that we are going to use is the “toaster” application, which lists the available toaster devices and their information, which is located in the “WinDDK\6000\src\general\toaster\exe\toast” directory of your Vista WDK installation. Refer to that location on documentation about the toaster application itself.

This sample is designed for use with Microsoft Visual C++/CLI 2005. (Note that this is incompatible with earlier, 2003 or before, edition of C++ with managed extensions) You can use:

  • Microsoft Visual C++ 2005 Express Edition.
  • Microsoft Visual Studio 2005 Standard Edition.
  • Microsoft Visual Studio 2005 Professional Edition.
  • or Microsoft Visual Studio 2005 Team System.

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

Getting Started

To create the service you have to use Visual Studio 2005, and the Microsoft Robotics Studio Command Prompt. Due to this we will have to do some changes to reuse the source out of the WDK. Let’s take it step by step:

Step 1: Create a new DSS C++ service

Open a Microsoft Robotics Studio Command Prompt. Create a new C++ DSS service with the following command:

Console
 >bin\dssnewservice.exe /service:myToasterSvc /language:cpp

This will create a folder with the service code in it. Open the solution from there with you Visual Studio 2005 C++ editor.

Step 2: Add toaster application code

From WinDDK\6000\src\general\toaster\exe\toast location in your WDK installation copy the toast.c file to your myToasterSvc service directory, and rename it to have a cpp extension. In Visual Studio right click on Source Files and select Add->Existing Item.. and point to the toast.cpp file that you just created. Since the whole project is managed, we need to explicitly say that this file will contain unmanaged code, by putting #pragma unmanaged in the beginning of toast.cpp.

Step 3: Configuring build

To build the project we need to add the build settings from the DDK sample in our project. They are configured in the sources file in WinDDK\6000\src\general\toaster\exe\toast directory and in the build environment command shell settings. Right click on you project in Visual Studio and select Properties. Here is the list of items you need to change:

  • Under C\C++ -> General add to Additional Include Directories the following folders: WinDDK\6000\src\general\toaster\inc and WinDDK\6000\inc\api from your WDK installation.
  • Under Linker -> General add to Additional Library Directories the following folder from WDK: WinDDK\6000\lib\wnet\i386
  • Under Linker -> Input add setupapi.lib to Additional Dependencies
  • Under Configuration Properties -> General change Character Set property from Use Unicode Character Set to Use Multi-Byte Character Set.

After you add these setting you should be able to compile your project, and get a couple of code errors due to syntax change from c to c++ for the toast.cpp file.

Step 4: Fixing toast.cpp

From the previous step after compilation you should see the following 2 errors:

  • error C2440: ‘=’ : cannot convert from ‘void *’ to ‘PSP_DEVICE_INTERFACE_DETAIL_DATA’
    c:\Microsoft Robotics Studio (1.5)\myToasterSvc\toast.cpp 155
  • error C2664: ‘SetupDiGetDeviceInstanceIdW’ : cannot convert parameter 3 from ‘BYTE *’ to ‘PSTR’
    c:\Microsoft Robotics Studio (1.5)\myToasterSvc\toast.cpp 306

The first problem can be fixed by just adding a cast:

 deviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc (predictedLength);

The second problem just needs the right cast:

 fSuccess = SetupDiGetDeviceInstanceId(hdi, &deid,
                                      (PSTR)currentToaster->szCompInstanceId,
                                      MAX_PATH, NULL);

After these errors are fixed you should be able to compile your service without errors. The toaster code that we added does not do anything useful, because we need to add the integration between it and the service code.

Step 5: Integrating code

The service that we are going to create will have as it’s state a list of toaster devices that are present in the system. To get the toaster device we will reuse the PrintToasterDeviceInfo() function, but change slightly how it works. We will want to gather the toaster device information, but instead of printing it to the console we will populate our service state with it. Here are the steps needed to make that integration happen:

Drop main method

Since we are going to reuse only the PrintToasterDeviceInfo() function we will not need the main function in the toast.cpp file. Our service will be started by the DSS runtime, so we don’t need this entry point.

Define new header file

Let’s create a header file for the toast.cpp file, by right clicking on your project and selecting Add -> New Item… -> Header File (.h) and call it toast.h.

Specify header files in source files

The header file that we created will be used in toast.cpp file and in myToasterSvc.cpp.

Define new data structure

In toast.h file, move the #include <wtypes.h> from the toast.cpp file to it and let’s define a structure that we will use to share the data between our managed and native functions. We will want to get the data between managed and native functions in as few calls as possible due to the performance hit of switching between managed and native code. Since we don’t know the length of the data that we want to get from the PrintToasterDeviceInfo() function, we will use a linked list so that it’s easy to expand. Here is what the structure should look like:

 typedef struct TOASTER_INFO {
    TOASTER_INFO(){nextToasterInfo= NULL;}
    TOASTER_INFO* nextToasterInfo;
    CHAR           szCompInstanceId[MAX_PATH];
    CHAR           szCompDescription[MAX_PATH];
    CHAR           szFriendlyName[MAX_PATH];
} *P_TOASTER_INFO ;

Change function signature

PrintToasterDeviceInfo() function with its current signature does not provide any information to the callers other than if it has found anything or not. Let’s change it so that it will also provide the new structure that we created. Make sure it’s declaration is in the toast.h file, here is what it’s new signature should look like:

 BOOL PrintToasterDeviceInfo(P_TOASTER_INFO* pFirstToaster);

Add allocation logic

Now let’s change how this function works in the toast.cpp so that it allocates and populates the TOASTER_INFO structure correctly. Since we don’t know up front how many devices we will find, we will allocate memory inside the loop where we enumerate over each toaster device. Since we don’t know if we will find even one, but our function will return the pointer to the first item in the linked list, we will need a custom logic to create the first element, and then any next element. Here is what that code should look like:

 if(*ppFirstToaster == NULL)
{
    *ppFirstToaster = new TOASTER_INFO;
    currentToaster = *ppFirstToaster;
}
else
{
    currentToaster->nextToasterInfo = new TOASTER_INFO;
    currentToaster = currentToaster->nextToasterInfo;
}

Populate the structure

Add the local variable that we will point to the current Toaster that we are working with: P_TOASTER_INFO currentToaster;. Next remove the szCompInstanceId, szCompDescription and szFriendlyName local variables and change the code that used them to point to their versions in the currentToaster local variable. Finally remove the calls to the printf function we will no longer need them.

Create new state

Now let’s change the service part of our code. Since we want the toaster information represented in the state of our service we need to change our current state definition. In the myToasterSvcTypes.h file add the following new class that will represent a single toaster:

 [DataContract]
public ref class myToasterInfo
{
public :
    [DataMember]
    String^ FriendlyName;
    [DataMember]
    String^ CompDescription;
    [DataMember]
    String^ CompInstanceId;
};

Now change the myToasterSvcState class so that it will only have a list of our toaster devices in it:

 [DataContract]
public ref class myToasterSvcState
{
public :
    myToasterSvcState();

    [DataMember]
    List<myToasterInfo^>^ Toasters;
};

Don’t forget to change the constructor of this class in myToasterSvcTypes.cpp so that it properly initializes that list:

 myToasterSvcState::myToasterSvcState()
{
    Toasters = gcnew List<myToasterInfo^>();
}

This should be enough to have the service state ready to be used for our needs.

Create new state renew method

we’ll need to repopulate our state to reflect the accurate data each time someone requests it using a Get operation. Since we have 2 operations defined – HttpGet and standard DSS Get, we will create a helper function that we will call from both of them. The function signature should look like this:

 myToasterSvcState^ myToasterSvc::RenewState()

Don’t forget to add it’s declaration to the myToasterSvc.h file, and change the two operations that we talked about above to use this function:

 void myToasterSvc::GetHandler(Get^ get)
{
    get->ResponsePort->Post(RenewState());
}

void myToasterSvc::HttpGetHandler(HttpGet^ httpGet)
{
    httpGet->ResponsePort->Post(gcnew HttpResponseType(RenewState()));
}

The way our service works we do not need to support the Replace operation. Remove it from service operations in myToasterSvcTypes.h file:

 public ref class Replace : Microsoft::Dss::ServiceModel::Dssp::Replace<myToasterSvcState^, PortSet<DefaultReplaceResponseType^, Fault^>^>
{
};

public ref class myToasterSvcOperations : PortSet<DsspDefaultLookup^, DsspDefaultDrop^, Get^, HttpGet^, Replace^>
{
};

And remove the handlers for it in the myToasterSvc.h and myToasterSvc.cpp files as well:

 void ReplaceHandler(Replace^ replace);

Arbiter::Receive<Replace^>(true, _mainPort, gcnew Handler<Replace^>(this, &myToasterSvc::ReplaceHandler))

void myToasterSvc::ReplaceHandler(Replace^ replace)
{
  _state = replace->Body;
  replace->ResponsePort->Post(DefaultReplaceResponseType::Instance);
}

Now everything is ready for the final step.

Add marshaling and cleanup logic to state renew method

in our RenewState method we need to create a new clean state instance, make a call to our native helper function, properly marshal and clean up the data that it returns. Here is the full code for that function, the comments show the particular parts that were mentioned:

 myToasterSvcState^ myToasterSvc::RenewState()
{
    // create a new empty state instance
    myToasterSvcState^ _state = gcnew myToasterSvcState();
    P_TOASTER_INFO currentToaster = NULL;
    P_TOASTER_INFO previousToaster = NULL;

    // call the native helper function
    if(PrintToasterDeviceInfo(&currentToaster))
    {
        if(currentToaster == NULL)
        {
            LogInfo(LogGroups::Console,"Current Toaster empty!");
        }

        while(currentToaster != NULL)
        {
            // populate the state, correctly marshal the strings 
            myToasterInfo^ toaster = gcnew myToasterInfo();
            toaster->FriendlyName = Marshal::PtrToStringAnsi(
                    (System::IntPtr)currentToaster->szFriendlyName);
            toaster->CompDescription = Marshal::PtrToStringAnsi(
                    (System::IntPtr)currentToaster->szCompDescription);
            toaster->CompInstanceId = Marshal::PtrToStringAnsi(
                    (System::IntPtr)currentToaster->szCompInstanceId);
            _state->Toasters->Add(toaster);

            //clean up the allocated memory
            previousToaster = currentToaster;
            currentToaster = currentToaster->nextToasterInfo;
            delete previousToaster;
        }
    }
    else
    {
        LogInfo(LogGroups::Console,"No toaster devices found!");
    }
    return _state;
}

Now that this is done you should be able to successfully compile your project.

Step 6: Try it out

Your toaster service should be fully compiled and the proxy assemblies generated in the bin folder of your Microsoft Robotics Studio installation location. Before you run it, you will need to add several Toaster devices to your computer. Please refer to the documentation located in the WinDDK\6000\src\general\toaster directory of your Vista WDR installation. It would provide you with the steps necessary to compile and run the tools and drivers needed to add Toaster devices to your system. Once done you should be able to run a command similar to this:

Console
 >Enum.exe -p 8

to add a toaster device to you machine. When you have some Toaster devices you can run a command similar to this one:

Console
 DssHost.exe /p:50000 /t:50001 /m:"myToasterSvc\myToasterSvc.manifest.xml"

out of your Microsoft Robotics Studio Command Prompt. Once the DSS node starts up you can access the state of the service by going to the following URL in your browser:

Console
 http://localhost:50000/mytoastersvc

If you used a different name for your Toaster service, you URL will be different. The state you see will be similar to this:

 <?xml version="1.0" encoding="utf-8" ?> 
<myToasterSvcState xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:d="http://schemas.microsoft.com/xw/2004/10/dssp.html" xmlns="http://schemas.tempuri.org/2007/08/mytoastersvc.html">
  <Toasters>
  <myToasterInfo>
    <FriendlyName>ToasterDevice08</FriendlyName> 
    <CompDescription>Microsoft Toaster With Coinstaller</CompDescription> 
    <CompInstanceId>{B85B7C50-6A01-11D2-B841-00C04FAD5171}\MSTOASTER\1&431A56F&0&04</CompInstanceId> 
  </myToasterInfo>
  </Toasters>
</myToasterSvcState>

Summary

In this tutorial you have learned how to do basic integration between Windows DDK and Microsoft Robotics Studio.

Here are the steps that we took:

In 1999 northwestern Turkey was struck by a 7.4 magnitude earthquake which resulted in the deaths of over 45,000 people and leaving millions homeless. The disaster was compounded by a five-day communication breakdown among the local authorities making it difficult to assess ground conditions and to coordinate relief efforts.   Motivated to assist these types of rescue efforts, we have worked with the Istanbul Municipality and Microsoft to develop RobotTurk – a Disaster Emergency Video System.

RobotTurkRobotTurk is a prototype Unmanned Aerial Vehicles (UAV) equipped with a camera that is capable of streaming live video of disaster struck areas to ground command stations. The helicopter carries onboard an eBox compute-unit that runs Microsoft Robotics Studio, allowing the robot to execute specific command issued by ground statation or to auto-fly or safely land. The ground stations utilizes Windows Server 2008 Media Services that capture, process and streams video. The disaster coordination users utilizes Microsoft Virtual Earth as a mapping tool and Silverlight streaming to show the overlaid video on the maps.
Control Panel
With Microsoft Virtual Earth as the mapping tool, users can select a new destination, add a new mission, and track the helicopter’s current position on the map. Images of the site are streamed using Silverlight.

Streaming Panel

The Microsoft Virtual Earth map on the right shows the actual position of the robot as well as additional flight data. Hosted on Windows Server 2008, the Web site uses Silverlight to stream the incoming images.

We currently have a prototype and most of the ground station and automous flight tasks have been implemented. The high-level architecture of the system is as follows:

Overview

http://RobotTurk.eu

Ce sont des superbes démonstrations sur Microsoft Robotics Studio de Olivier’s Blog.
Découvrez Microsoft Robotics Studio
Découvrez Microsoft Robotics Studio

Découvrez Microsoft Robotics Studio avec MSDN
Découvrez Microsoft Robotics Studio avec MSDN

Voilà, après quelques recherches, j’ai trouvé que l’entreprise Parallax, qui fournit des produits robotiques pour apprendre et développer très intéressants, a sorti un nouveau kit de BoeBot: le kit de BoeBot normal avec la carte de Bluetooth qui permet de synchroniser le robot avec l’ordinateur à travers Microsoft Studio Robotics (MSR). Voilà quelques images que j’ai trouvé sur Olivier’s Embedded blog: click here

Parallax and Microsoft have collaborated to combine the power of Microsoft® Robotics Studio with the versatile and easy to use Boe-Bot® Robot. With the Boe-Bot Robot Kit for Microsoft Robotics Studio, you can develop PC code to monitor and orchestrate the activities of one or more Boe-Bot robots, all via Bluetooth wireless.

To learn more about the kit, free downloads, documentation and tutorials, check out the Boe-Bot Kit for Microsoft Robotics Studio product page.

To learn more about Microsoft Robotics Studio, go to the Microsoft Robotics Studio page.

The Boe-Bot Kit Microsoft Robotics Studio

This kit’s hardware includes our popular Boe-Bot robot full kit and the eb500 Bluetooth module, making it possible for the Boe-Bot robot to communicate with a PC’s Bluetooth radio. All the software you’ll use with the kit is available for free download, including the following:

  • The Parallax BASIC Stamp Editor
  • PBASIC example programs for the Boe-Bot robot
  • The latest Microsoft Robotics Studio Community Technical Preview (CTP) release
  • Microsoft programming languages such as Microsoft Visual C# and VB.Net.

The kit’s documentation and example code provide tutorials and demonstrations that use a Microsoft Robotics Studio “service” to control the Boe-Bot robot. They also demonstrate how to manipulate the Boe-Bot robot’s PBASIC and the PC’s C# code for PC programmed wireless Boe-Bot robot monitoring and control. After that, you’ll be ready to tackle Microsoft’s tutorials, which show how to leverage the Robotic Studio’s BASIC Stamp 2 services for PC navigation based on sensor inputs as well as GUI development.

Check out the Boe-Bot Kit for Microsoft Robotics Studio.
For additional assistance with the Robotics Studio hardware contact us.

About Microsoft Robotics Studio

Microsoft Robotics Studio provides an end-to-end robotics development environment for hobbyist, academic, and commercial robotic developers. Microsoft Robotics Studio is a Windows-based environment that offers the following key features and benefits:

    End-to-End Robotics Development Platform: Microsoft Robotics Studio enables developers to generate modular services for hardware and software, allowing users to interact with robots through Windows-based or Web interfaces. Developers can also simulate robotic applications using realistic 3D models with AGEIA™ PhysX™ Technology. AGEIA™ is a pioneer in hardware-accelerated physics, enabling real-world physics simulations with robot models. Simulations can be accelerated through hardware acceleration using the AGEIA™ PhysX™ processor (Available in PhysX™ Accelerator add-in cards for PCs).Lightweight services-oriented runtime: Microsoft Robotics Studio provides a lightweight service-oriented runtime. Using a .NET-based concurrency library, it makes asynchronous and distributed application development simple. The service-oriented message-based architecture makes it possible to realization of highly complex applications through the composition and orchestration of simpler services.

    Scalable and extensible platform: Microsoft Robotics Studio programming model can be applied for a variety of robot hardware platforms, enabling users to transfer their learning skills across platforms. Third-parties can also extend the functionality of the platform by providing additional libraries and services. Both remote (PC-based) and robot-based (autonomous) execution scenarios can be realized using a selection of programming languages, including those included in Microsoft Visual Studio and Microsoft Visual Studio Express languages (C# and VB.NET), as well as Jscript and Microsoft Iron Python as well as third-party languages that conform to its services-based architecture.

For additional assistance with the Robotics Studio software the Robotics Studio Newsgroup is an excellent source of information.

AGEIA and PhysX are trademarks of AGEIA Technologies Inc.

Blog Stats

  • 241,460 hits

Archives

RSS Flux inconnu

  • Une erreur est survenue ; le flux est probablement indisponible. Veuillez réessayer plus tard.