Introduction
Visual Storms is an add-in for VisualStudio.NET that allows you to write managed programs in whatever language you like and run them on the popular Lego Mindstorms: the programmable Lego Brick. The SharpStorms compiler transforms MSIL in .NET assemblies into the bytecode consumed by the standard Lego VM running on the brick.
Does this means that you can run .NET applications on the brick? Of course not: you should inherit from given classes, make use of custom attributes, and so on. Anyway you can use a real world programming environment to program the brick, and this can be useful to beginners.
Notes
The compiler can be used also without VS.NET.
Because the compiler maps IL to bytecode, sometimes the compiler outputs IL sequences we don't handle correctly. We are helping people in fixing these problems, though is someone is willing to help, help will be really appreciated!
Why is in Robotics4.NET?
VisualStorms is a project not directly related to Robotics4.NET. Nevertheless it has been our start with .NET and robots. Moreover, within the package you'll find all the machinery required to generate bytecode for mindstorms, and this can be useful to target Lego Mindstorms platform. Perhaps in the future we will target Mindstorms with Robotics4.NET.
Example
The following example shows a line walker (assuming a suitable architecture). You can see how custom attributes are used to indicate how tasks are distributed in the final code. The class inherits from a class representing the capabilities of the brick (Scout, RCX2, ...). You can use only integer variables (due to limitations of the architecture).
Show
using System;
namespace LegoExamples {
public class LineWalker : VisualStormsTypes.RCX2 {
public int A;
public int C;
public int Changed;
[VisualStormsTypes.FunctionType(VisualStormsTypes.Function.Task, 0)]
public void Main() {
A = 1;
C = 0;
Changed = 0;
SetSensor(VisualStormsTypes.Sensor.Sensor2, VisualStormsTypes.SensorType.Light);
SetSensorMode(VisualStormsTypes.Sensor.Sensor2, VisualStormsTypes.SensorMode.PctFullScale);
On(VisualStormsTypes.Motor.A | VisualStormsTypes.Motor.C);
Forward(VisualStormsTypes.Motor.A);
Reverse(VisualStormsTypes.Motor.C);
SetMotorsPower(VisualStormsTypes.Motor.A, 7);
SetMotorsPower(VisualStormsTypes.Motor.C, 0);
Start(1);
Start(2);
}
[VisualStormsTypes.FunctionType(VisualStormsTypes.Function.Task, 1)]
public void Watch() {
while(true) {
if ((Sensor2() > 52) && (Changed == 0)) {
A = A == 1 ? 0 : 1;
C = C == 1 ? 0 : 1;
Changed = 1;
}
if (Sensor2() < 52)
Changed = 0;
}
}
[VisualStormsTypes.FunctionType(VisualStormsTypes.Function.Task, 2)]
public void Walk() {
while (true) {
if (Changed == 1) {
if ( A == 1 )
SetMotorsPower(VisualStormsTypes.Motor.A, 7);
else
SetMotorsPower(VisualStormsTypes.Motor.A, 0);
if ( C == 1 )
SetMotorsPower(VisualStormsTypes.Motor.C, 7);
else
SetMotorsPower(VisualStormsTypes.Motor.C, 0);
}
}
}
}
}