So I had found the C# DLL’s that seemed to generate VM byte code. At this point I had grown weary of digging around in LabVIEW and attacked the problem from another angle.
I took a look at the EV3 Brick. I connected it to my computer and started the LabVIEW Brick Memory Browser. With that browser I found out that I can fetch files from the Brick, so I tried to fetch a program. It worked, and I was able to download a program file that executes on the Brick.
The program in question was a simple Play->Start Medium Motor->End, and it had resulted in a file weighing in at 334 bytes of VM byte code, with the file extension .rbf. Without knowing anything about the file format I opened up the file in my favorite hex viewer and quickly found that the first 4 bytes was always the int 0x4C45474F, which spells out ‘LEGO’, and the next 4 bytes, when read as a little endian 32 bit integer, always contained the size of the file. After that started the confusion.
I created a bunch of permutations of the same program, downloaded the compiled VM byte code to my computer, compared the different permutations and found a bunch of similarities and also a lot of differences. I tried different blocks (medium motor, large motor) and I tried the same block with different parameters (loop X times, wait X seconds, different values of X). Changing values of X yielded the value of X as the only diff in the binary files, as expected, but changing between medium and large motor yielded a massive change in the byte code, which I hadn’t quite expected.
So now I had a massive (relatively speaking) binary of VM byte code, and I had the C# class that would generate this byte code. All I had to do now was to use the LabVIEW C# class to generate VM byte code from Unity and see if would boot on the Brick!
While digging around in the LabVIEW app data for information on the ev3p files I found that LabVIEW was built in Mono!
Mono is an open source C# environment that runs on multiple platforms, not just Windows. I have been using Mono extensively in my work for a bit over a year since we use Unity where I work. I figured that if the code for LabVIEW is written in managed C# and compiled into C# DLL’s then those DLL’s could be used by any Mono project, even one written in Unity. I was hoping I could use the code for LabVIEW and just write my own graph editor.
So I picked a few of the LabVIEW Mono DLL’s and loaded them into MonoDevelop to look at what they provided, and maybe have a peek at their code. I found quite a bit of interesting information.
For example I found the class NationalInstruments.LabVIEW.VI.VirtualMachine.Runtime.PBrick that was building buffers that seemed to be commands for communication between a computer and the EV3 Brick. Then I found the class NationalInstruments.LabVIEW.VI.VirtualMachine.Runtime.Rxe that seemed to describe VM code. I found an enum named RxeOpCode that contained the values Add (value 0), Compare (value 17) and SystemCall (value 40).
After that I found an extremely intriguing class named NationalInstruments.LabVIEW.VI.VirtualMachine.Runtime.Vivm. The reason why this was so interesting was because when I poked around the XML files describing the LabVIEW blocks they where all mentioning blocks by referencing .vix files. For example there was a block that was referencing a file called MotorSpeedSensor.vix.
And now it seems like I’ve found the class that can help me generate VI VM code! In the VI.VirtualMachine.Runtime.Vivm I found an enum called OpCode that contained values like opAddFloat32 (value 41), opCallByRef (value 2) and opSleep (value 7). This class also contained methods like WriteInstruction, WriteOpCode and WriteArg. It seems like this class could help me to bypass not only the graph builder in LabVIEW but also converting from ev3p XML files straight to byte code for the VM running on the Brick.
So I’ve used LabVIEW a bit. (Is that even what it is called? The LEGO Mindstorms programming tool.) It’s not that great for me. It is unresponsive, I have a hard time getting an overview, the program doesn’t seem to allow me to iterate on my code as quickly as I’d like and I feel like I can’t do what I want. I have an idea of what I want to do but I can’t figure out how to get there with LabVIEW. So I started looking into other options.
I had already ruled out existing homebrew tools (the ones I could find at least) so the next option is to do my own tool.
Initially I figured I could do a graphical tool, similar to LabVIEW, but nicer to use. (I fully understand if you laugh at this idea, it’s not the best idea I’ve ever had) So I started looking into the ev3p file format. I found out that it was basically just a bunch of zipped XML files, and each XML file described a graph in my program. I found the XML nodes that described the layout and parameters, the nodes that described the wires that goes between blocks, and I found the XML that described my own blocks.
I also dug into the app content of LabVIEW to find the definitions of the built-in blocks. I.e. what parameters they accept, their types and ranges, etc.
After a while of digging around I understood that yes, I could do my own tool that generate ev3p-files identical to what LabVIEW generates, but it all seemed to cumbersome, and I was concerned I would need to understand each block to be sure it worked fine. Also, if I were to generate my own ev3p-files I would still need to load them into LabVIEW and use LabVIEW to download the program to the device.
But while digging around in the app data for LabVIEW I found something much more interesting!
Welcome to my blog where I go on adventures in LEGO Mindstorms EV3 Virtual Machine.
I have had a few days of experimenting and I will bring you up to speed in a second, but first I’d like to explain how I got into this situation in the first place.
Around christmas last year LEGO Mindstorms EV3 caught my eye. I was completely fascinated by what seemed like a world of infinite possibilities. There was this computer running Linux that was hooked up a couple of sensors and motors. I have always been intrigued by the cross between hardware and software and I’ve been looking for a way into that cross section. And Mindstorms looked perfect!
Before I bought it I looked into the many ways of programming the device besides the official tools. I read about BricxCC, LeJOS, NXC and all the other options on Wikipedia. It seemed like I could do anything! EV3 looked like the next toy, so I went out and bought a kit.
And then nothing.
My brother and I built theTrack3r, it worked, and I was excited for a minute or so. I started the LabVIEW programming tool where you drag and drop blocks on a graph to build your program and that was fun for a bit, but since I’m used to “regular” programming, where you type the code rather than building graphs, I felt hindered and a bit bored.
I started looking at BricxCC and found out that most of the tools seemed to be Windows only, and it also didn’t seem to support EV3. (Last time I checked http://bricxcc.sourceforge.net/ev3_info.html it said “Coming soon“)
So I looked at LeJOS but that require me to install a modified version of the OS on by Brick, which I’m not too keen on yet. And with Java I get further away from the LEGO Mindstorms “feel”, and I’m not terribly interested in using the Java language.
So after looking into existing tools I figured I wasn’t happy with any of them (that I could find) and I set out to investigate what had always been in front of me. The stuff that is provided by LEGO.