Click here to Skip to main content
14,923,486 members
Articles / Desktop Programming / WPF
Posted 12 Nov 2010


9 bookmarked

Lego Mindstorms NXT 2.0 Bot controlled using MRDS

Rate me:
Please Sign up or sign in to vote.
4.43/5 (4 votes)
27 Nov 2010CPOL3 min read
A Lego Mindstorms NXT 2.0 Bot controlled using Microsoft Robotics Developer Studio


In this article, I’m going to explain about creating a fully computer controlled Lego Mindstorms NXT 2.0 Bot (with camera mounted on it) using Microsoft Robotics Developer Studio (MRDS).


My previous article Microsoft Robotics Service for LEGO NXT 2.0 should be useful if you haven’t created any service using the Studio.



Check out this video.

Using the Code

Create a MRDS Service and add the partners - NxtDrive and NxtBattery. This will automatically declare and instantiate an object for BatteryOperations and an object for DriveOperations. Please add one more for DriveOperations as the code mentioned below:

/// <summary>
/// NxtBattery partner
/// </summary>
[Partner("NxtBattery", Contract = battery.Contract.Identifier,
	CreationPolicy = PartnerCreationPolicy.UseExistingOrCreate)]
battery.BatteryOperations _nxtBatteryPort = new battery.BatteryOperations();

/// <summary>
/// NxtDrive partner
/// </summary>
[Partner("NxtDrive", Contract = drive.Contract.Identifier,
	CreationPolicy = PartnerCreationPolicy.UseExistingOrCreate)]
drive.DriveOperations _nxtDrivePort = new drive.DriveOperations();
drive.DriveOperations _nxtDriveNotify = new drive.DriveOperations();

Add a new class library project to the solution, and add an interface to it. This project needs to be referenced in the MRDS Service and the WPF UI projects (will explain the UI project later).

public interface IMyLegoCarService
	double GearPower { get; set; }
	long LeftEncoderCurrent { get; set; }
	long RightEncoderCurrent { get; set; }
	double LeftPowerCurrent { get; set; }
	double RightPowerCurrent { get; set; }
	double BatteryPower { get; set; }
	void Drive(DriveAction driveDirection);
	void StopEngine();

Change the MRDS Service in such a way that it implements this interface. Values for all the properties but the first property (GearPower) will be set in the service, and they will be retrieved and used in the UI layer.

Now, add a new WPF project. Declare a property named Service of type IMyLegoCarService, and add a constructor, something like this:

 public Dashboard(IMyLegoCarService service) : this()
    Service = service;
    Service.GearPower = 0;
    brsr_ipcamera.Navigate(new Uri


    uiTimer = new DispatcherTimer();
    uiTimer.Interval = TimeSpan.FromSeconds(1);
    uiTimer.Tick += uiTimer_Tick;

This constructor should be called from the Service’s constructor, so that the service and the UI will be on the same thread. Here “brsr_ipcamera” is the web browser control to display the ip camera’s image/video (in my case my iphone). I added an HTML page to my webserver displaying only the video from the camera. Add a timer control to display the information retrieved from the service periodically. Here I’ve used WPF Dashboard Controls’ dial controls as speedometers (for left motor front, left motor reverse, right motor front and right motor reverse), odometer control as odometer and progress bar control as fuel gauge. Left/Right Power Current properties were used to initialize the speedometers. Left/Right Encoder properties were used to initialize the odometer, these properties basically give us the degrees that the servo motors rotated. Using the formula: distance = Convert.ToInt32(Math.Abs(currentEncoderCurrent) / 360 * 2 * 3.14 * 0.75, we can calculate the distance covered. Here, pi = 3.14 and 0.75 is the radius of the wheels.

Image 1

Coming back to the service. Declare and/or instantiate the following classes:

wpf.WpfServicePort _wpfServicePort;
drive.SetDriveRequest _nxtSetDriveRequest = new drive.SetDriveRequest();
battery.BatteryState _nxtBatteryState; 

WpfServicePort is used to invoke the WPF UI, SetDriveRequest to rotate the motors and the BatteryState to get the battery information.

Add a port named “TimerTick” to the service types similar to the automatically created ports “Get”, “Subscribe”, etc. Now your serviceoperations class declaration will be something like this:

public class MyLegoCarServiceOperations :
	PortSet<DsspDefaultLookup, DsspDefaultDrop, Get, Subscribe, TimerTick>
public class TimerTick:Update<TimerTickRequest, PortSet<DefaultUpdateResponseType, Fault>>
	public TimerTick()
	    : base(new TimerTickRequest())

public class TimerTickRequest

Modify the service’s start method something like this:

protected override void Start()

private IEnumerator<ITask> DoStart()
    DispatcherQueue queue = new DispatcherQueue();

    this._wpfServicePort = wpf.WpfAdapter.Create(queue);

    // invoke the UI
    var runWindow = this._wpfServicePort.RunWindow(() => (Window)new Dashboard(this));
    yield return (Choice)runWindow;

    var exception = (Exception)runWindow;
    if (exception != null)
	yield break;

    // Subscribe to partners
    var subscribe1 = this._nxtDrivePort.Subscribe(_nxtDriveNotify);
    yield return (Choice)subscribe1;


    // Activate independent tasks
		(true, _nxtDriveNotify, DriveEncoderHandler),
	Arbiter.Receive(true, _timerPort, TimerHandler)

    // Start operation handlers and insert into directory service.

private void StartHandlers()
    // Activate message handlers for this service and insert into the directory.


Timerport is used to retrieve the battery information periodically.

public IEnumerator<ITask> TimerTickHandler(TimerTick incrementTick)

    battery.Get batteryGet;
    yield return _nxtBatteryPort.Get(GetRequestType.Instance, out batteryGet);
    _nxtBatteryState = batteryGet.ResponsePort;
    if (_nxtBatteryState != null)
	BatteryPower = _nxtBatteryState.PercentBatteryPower;

    yield break;

void TimerHandler(DateTime signal)
    _mainPort.Post(new TimerTick());
	Arbiter.Receive(false, TimeoutPort(3000),
	    delegate(DateTime time)

DriveEncoderUpdate to retrieve the information from the servo motors.

private void DriveEncoderHandler(drive.DriveEncodersUpdate statistics)
    LeftEncoderCurrent = statistics.Body.LeftEncoderCurrent;
    RightEncoderCurrent = statistics.Body.RightEncoderCurrent;
    LeftPowerCurrent = statistics.Body.LeftPowerCurrent;
    RightPowerCurrent = statistics.Body.RightPowerCurrent;

Create an enum named “DriveAction” in the common class library project. This is to handle the keyboard or the click events from the UI Layer.

public enum DriveAction

Implement the Drive method in the service.

public void Drive(DriveAction driveAction)
    switch (driveAction)
	case DriveAction.Front:
	    _nxtSetDriveRequest.LeftPower = -GearPower;
	    _nxtSetDriveRequest.RightPower = -GearPower;

	case DriveAction.Back:
	    _nxtSetDriveRequest.LeftPower = GearPower;
	    _nxtSetDriveRequest.RightPower = GearPower;
	case DriveAction.Left:
	    _nxtSetDriveRequest.LeftPower = -.4;
	    _nxtSetDriveRequest.RightPower = .4;

	case DriveAction.Right:
	      _nxtSetDriveRequest.LeftPower = .4;
	    _nxtSetDriveRequest.RightPower = -.4;
	case DriveAction.Stop:

Hope this helps in creating a service for controlling your Bot.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Software Developer (Senior)
United States United States
No Biography provided

Comments and Discussions

NewsNice project Pin
Ima Dirty Troll24-Nov-12 7:41
MemberIma Dirty Troll24-Nov-12 7:41 
GeneralRe: Nice project Pin
gokulnathm26-Nov-12 18:02
Membergokulnathm26-Nov-12 18:02 
QuestionWPF Service Port Run Window Pin
riggaroo26-Mar-12 3:29
Memberriggaroo26-Mar-12 3:29 
AnswerRe: WPF Service Port Run Window Pin
gokulnathm29-Mar-12 19:49
Membergokulnathm29-Mar-12 19:49 
GeneralHelp with Visual Studio Interface Pin
RoboTechNerd8-Apr-11 6:49
MemberRoboTechNerd8-Apr-11 6:49 
GeneralRe: Help with Visual Studio Interface Pin
gokulnathm9-Apr-11 11:25
Membergokulnathm9-Apr-11 11:25 
GeneralRe: THANKS Pin
RoboTechNerd11-Apr-11 9:10
MemberRoboTechNerd11-Apr-11 9:10 
GeneralThanks Pin
MisterHonda28-Dec-10 13:05
MemberMisterHonda28-Dec-10 13:05 
GeneralRe: Thanks Pin
gokulnathm28-Dec-10 13:32
Membergokulnathm28-Dec-10 13:32 
GeneralCamera app Pin
ergysr2-Dec-10 0:29
Memberergysr2-Dec-10 0:29 
GeneralRe: Camera app Pin
gokulnathm2-Dec-10 14:43
Membergokulnathm2-Dec-10 14:43 
GeneralMy vote of 5 Pin
linuxjr28-Nov-10 5:50
professionallinuxjr28-Nov-10 5:50 
GeneralMy vote of 5 Pin
roshanm15-Nov-10 8:12
Memberroshanm15-Nov-10 8:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.