Sunday, October 12, 2014

MCPI-Scratch: Lines and Circles





The initial release of MCPI-Scratch came with support for the basic operations to move a player around and to set blocks. But it takes a lot of work to create interesting shapes using those primitives - especially for kids that are using Scratch as their introduction to programming. So we thought it would be useful to create a couple of new operations to make it easier to create interesting shapes.

Lines and Circles

Its easy to use loops to create lines with the existing primitives, but doing that results in lines that simpy align with the x,z axes in minecraft (or go at 45 degrees). Creating a line between any two points is a bit harder so we created an operation to make it easier.

The process of taking a shape (such as a line or circle) and converting it to a set of points on a grid (like minecraft) is called Rasterisation. There are some well-known algorithms for performing this in computer graphics - Bresenham's Line Algorithm and the Midpoint Circle Algorithm (or Bresenham's Circle Algorithm).

There are plenty of implementations of these available online in a variety of languages so it was quite simple to find them (line, circle) and adapt them to MCPI-Scratch.

setLine

setLine allows you to draw a line between any two x,z coordinates at a given height (y coord).

There is a sample Scratch script (lines.sb2) that adapts an online example to draw lines along the radius of a circle at various degree increments



setCircle

Similarly, setCircle draw a circle with a given center point (x,z) at a given height (y).

The provided example (circleWork.sb2) draws a dome by using a loop to draw decreasing radius circles at increasing heights



We've also used it to dig an ampitheatre by inverting the dome and setting the blockType to Air


Tuesday, September 16, 2014

MCPI-Scratch: A Scratch Extension application to program Minecraft


The last blog post - Scratch, Minecraft and Raspberry Pi: how they fit together - explained different alternatives for programming Minecraft using Scratch. Unfortunately the easy alternatives are currently limited running everything on a Raspberry Pi using an older version of Scratch.




So I've been messing around with the Extension capabilities in Scratch 2 and have a helper application that will allow you to manipulate Minecraft using a standalone Scratch 2 editor.


First a quick recap:

Scratch2 has a mechanism for interacting with external programs - the Scratch Extension Protocol.  Scratch speaks HTTP to a helper app running on the same machine which in turn can then interact with any other program. All the details are in that earlier blog post.

I've chosen to write the helper app in python which interacts with the Minecraft Pi Protocol. That gives flexibility to connect to either a local CraftBukkit server with the RaspberryJuice mod or to Minecraft Pi Edition. We have both setups and its been tested on both of them.

Installation

The code is available over on github and the README has the most up to date details about how to install and get started but I'll do a quick summary here also.

If you are comfortable with git then you know how to clone the repo. If not, then the easiest thing is to download the project as a zip file.



Download and install Scratch 2 offline editor.
  • Scratch and the helper app must be running on the same machine
Choose which Minecraft setup you wish to use. Either:
  • Minecraft Pi Edition or
  • CraftBukkit server with the RaspberryJuice mod

Getting Started

You will need to start the applications in the correct order.

1. Start Minecraft
  • This must be running before you start MCPI-Scratch because the application attempts to create a connection on startup and will fail if Minecraft is not running.
  • If you're using the Minecraft Pi Edition then you are done
  • If you are running the CraftBukkit server with the RaspberryJuice mod then you will need to use the Minecraft launcher to also start a client to connect to the server
  • The helper app needs a player in the world in order to orient itself and send position information back to Scratch
  • A useful tip is to use the t cmd to open the chat console in Minecraft and get control of the mouse so you can get to another application.
2. Start MCPI-Scratch. 
  • The application attempts to connect to localhost by default.
  • $ python ./mcpi-scratch.py
  • Use the -m host cmd-line arg to specify minecraft running on another machine
  • For instance, if you are connecting to Minecraft running on a Rasperry Pi (change the IP in the example for the IP address of your RPi)
  • $ python ./mcpi-scratch.py -m 192.168.1.117
3. Start Scratch. 
  • When the editor loads, shift-click the File menu and select Import experimental HTTP extension and select the file mcpi-scratch.s2e in the MCPI-Scratch install directory. This file specifies the new blocks to use in Scratch and the messages they send/receive with the MCPI-Scratch app.
  • You should now be able to select the More Blocks section in Scratch and see the Scratch Blocks that can be used in scripts



You should now be ready to write scripts to interact with Minecraft.

Blocks

In the initial release I've only implemented blocks for the following commands
  • postToChat
  • getPlayerPos
  • setPlayerPos
  • setBlock: this includes a flag to set the block using absolute coordinates or relative to the player position
  • setBlocks
This is enough to get started. I'll add more blocks to represent the Minecraft Pi Protocol API if people are interested.


There is a good API reference at the StuffAboutCode blog and you can easily adapt the python examples from that blog to Scratch programs

Examples

The installation as a couple of sample scripts

postToChat

The postToChat.sb2 script is a good way to test your set up.

Simply open that file from the scratchExamples directory, click on the script in the Scratch editor, and it should print a hello message in the minecraft chat console.

If this is working then you're ready to try the other blocks.


simpleHouse

The simpleHouse.sb2 script creates a very simple square house using setBlocks block.


It also has some other statements to both clean up and test the other blocks.

rainbow

An adaptation of the rainbow example that is popular in python api tutorials for minecraft
(it took a painfully long time to figure out that the sine function in python and Scratch operate on radians and degrees respectively - fun with debugging...)



That's it. Give it a whirl.

Thursday, September 4, 2014

Scratch, Minecraft and Raspberry Pi: how they fit together

My son has been learning programming with Scratch. But moving sprites around the screen will only keep his attention for so long, so we've been trying to figure out how to get Scratch programs to manipulate Minecraft. 


The short answer

The short answer is  "Yes, you can". The longer is answer is more involved and complicated so I thought I'd collect my notes for others that are trying to figure it out.






The longer answer

Can you get Scratch to manipulate Minecraft? 
Well, it depends on which version of Scratch you want to use and also which version of Minecraft you want to use. 

To understand all the combinations and consequences you need to understand a bit about how they interact.


Scratch doesn't interact with Minecraft directly. You need to use a Scratch extension to interact with an external program. That external program then provides the interaction between Scratch and Minecraft.





The complication is that the extension to Scratch and the API/MOD for Minecraft are dependent on the versions of the respective applications you want to use.


Lets start with the easiest alternative - do everything on a Raspberry Pi.


The good news is that it just works. You can go and grab a copy of all the necessary bits at scratch2mcpi


The installer has all the bits you need. Just fire it up, then copy and modify some of the example applications.


There is also a 2nd package you can get which provides a Scratch programming wrapper to Martin O'Hanlon's python library for Minecraft Turtle Graphics. Again, the whole lot can be downloaded as a single installer and you can see the example projects on the author's Scratch area.

To use scratch for minecraft turtle graphics you need to open one of the examples (or the template project), modify it as you want and save as a new project. (This limitation is due to the way Scratch on the RPi deals with external programs... As we shall see)


The not so good news is that these two packages are kind of limited and you need to use an older version of Scratch. To understand the limitations lets have a look at how it works.





The version of Scratch you get on the RPi is v1.4 but the current version of Scratch is now v2.0.

Unfortunately the latest standalone version of Scratch doesn't run on the RPi because its built on Adobe Air which doesn't run on the RPi architecture. So you're stuck with v1.4. 


The limitation is that the way Scratch handles interaction with external programs is pretty limited in v1.4 but has received a nice upgrade in v2.0. 


Scratch 1.4 uses its Remote Sensors Protocol to communicate with external applications. This provides low-level socket communication between Broadcast messages from Scratch 1.4 and the external app. There is a small python project, ScratchPy which talks that protocol. The scratch2mcpi project builds on scratchpy to speak to Minecraft.




However, Minecraft on the RPi is not the same as regular Minecraft. Minecraft Pi Edition is a cut-down version similar to the version of minecraft that you get on your phone or tablet (or ps3/xbox console). It provides an API (both python and java) which enables external programs to interact with the world using the Minecraft Pi Protocol. This protocol isn't available on regular minecraft, just the RPi version (* there is an exception which I'll come back to...).


So, the available software only lets you interact between Minecraft and Scratch programs on the RPi. 


But what if you want to use Scratch v2.0 or a version of Minecraft that is not the Pi Edition? At the moment you can't. The only way to use Scratch 2.0 is to run it somewhere other than a RPi (Mac, Win, or Linux(x86)).


Scratch2 has a new mechanism for interacting with external programs - the Scratch Extension Protocol. At this time you need to use a standalone (not web) version of Scratch though there are plans to make it possible to use the protocol from the webapp version of the scratch editor.


The extension protocol speaks HTTP to a helper app running on the same machine as Scratch. That helper app can then interact with any other program. This approach is more flexible than the Scratch v1.4 mechanism that works for scratch2mcpi.


There isn't (or I can't find) a Scratch 2 extension app that interacts with Minecraft. But here is how it should work:




Lets start with the helper app. When you define a helper app you have the opportunity to define your own blocks that can be used in Scratch scripts. When these blocks are used in the scripts Scratch sends http messages to the helper app - simple GET messages with the operation and data from the block passed along. The helper app can then pass these along to Minecraft. Its also possible to have blocks that listen to the helper app for incoming information. Scratch continuously polls the helper app for new information so you could read info from Minecraft and use it in a script (not super efficient but it works...)

This is all much nicer than the simple Broadcast messages that are available in Scratch v1.4.

As an example, here is a screenshot of a test helper app I've been toying with to test out communication with Minecraft. The "post to chat" block will send a message via the helper app to the Minecraft Pi edition API to print a message to the players chat window. There is also a block which polls the app to return the players position to use in a script.



Now we can cover the options this creates on the Minecraft side.
The helper app is just a small http server which listens for HTTP requests from Scratch and you can then do what you like. There are a number of alternatives for interacting with Minecraft.

  1. You could use the same mcpi api to communicate with Minecraft Pi Edition running on an RPi
  2. Or you could connect to a full Minecraft server that has a MOD to provide an API to external clients. For example, you could write a http server in Node and then use the node-minecraft npm or the ScriptCraft mod to integrate to Minecraft. 
  3. Finally you could actually use Minecraft Pi Protocol on a Minecraft server that isn't running on the RPi. The RaspberryJuice mod provides a slightly cut-down version of the Pi Protocol which allows you to integrate with the same API on both full servers and Pi Edition.

Next Steps

If you want to start using Scratch and Minecraft together, then you need to use one of the alternatives available on the Raspberry Pi. The next step is to see if I can get a Scratch2 helper app to expand those possibilities...


Saturday, August 16, 2014

MOSS meets Node-RED



Connecting a MOSS bot to external devices and open data feeds using Node-RED

The other day I was reading Simen's story about joining up his Raspberry Pi with Minecraft and arduino-based sensors/servos using Node-RED and wondered how it would work with MOSS.

MOSS is a great system for quickly creating small robot platforms and Node-RED is platform for quickly prototyping integration solutions between internet enabled devices and data sources. Joining them up is actually very easy.

Although there isn't yet a publised API for MOSS, if you use the Scratch extension for MOSS, you can actually get an HTTP (RESTish) interface to the bluetooth block which is dead simple to use from Node-RED.

Step 0: Create a MOSS bot with the bluetooth brain block

Start with a simple bot that has:
  • Extended Battery
  • Double Brain
  • Something that can be controlled
    • The Pivot is good to get started but you could also use a Motor

Step 1: Install the MOSS Scratch Extension

Go and grab the Moss Scratch extension application. This app creates a little webserver which communicates between the MOSS bluetooth block and a running Scratch instance using HTTP.
We'll be using Node-RED to communicate with that HTTP server instead of Scratch. Actually, you can use this technique to control your MOSS bot with anything that speaks HTTP.


Follow the quickstart guide for the Scratch extension app. You don't need to actually start Scratch. Just get a connection between the MOSS Scratch app and your bluetooth block.
Once you have the 2nd picture above, then you're ready to go. 
The extension app runs on port 41585 and you can check the connection already if you like with curl.

Step 2: Install Node-RED

Node-RED is a Node.js application so you'll need to have that installed already. There are plenty of guides online for install Node.js. You can then install Node-RED using the simple npm method. Adafruit has a nice tutorial for installing both on a Raspberry Pi.

Start Node-RED and bring up the editor in a browser window.

Step 3: Create a Flow to control MOSS from HTTP

From the Input section, add an Inject
From the Functions section, add an HTTP Request node.
From the Output section, add a Debug.
Join the three together.


(The image shows a second set of icons which repeats the flow to move the bot to the original position again. You can also add them).

When we click on the left of the Inject Node it will fire off a HTTP request and then pass through a messge to the debug node. The trick is simply to get the HTTP request created correctly.

Double click the first HTTP node to bring up the properties.
The URL to control the pivot uses the following template:

http://machine:41858/set_face_value/<btooth_face>/<value>

My bot has face #2 from the brain connected to Data In for the Pivot.

The MOSS getting started page explains that pivots and motors (as well as sensors) use values as a percentage.

The default position for the pivot is 50, so for the first test we'll set it to 40. So set the URL to

http://localhost:41858/set_face_value/2/40

You can repeat the process on the 2nd HTTP Node to set the Pivot back to 50

http://localhost:41858/set_face_value/2/50

(You can actually set this URL straight into your browser or curl to check if its all working)

That's it. Click on the left part of the Inject Nodes and the MOSS bot should nod its face up and down.

(click the img to get to the full video)

Step 4: More interesting example - the-train-is-here-bot

The nodding bot is pretty simple but you can achieve the same results just by putting the url direct into your browser or curl. The nice part about Node-RED is how quickly you can integrate with other devices and data sources because Node-RED handles all the plumbing code. So, a bit more interesting example: a bot that will let me know when the train is at the local station.

The Oslo public transport system offers a public API for its travel information. Both timetables and realtime travel information. I'll make a quick flow that will check the realtime information at my local trainstation and get the same bot to look up and point to the trainstation if the arrival time of the next train is under 5 minutes.

First I used the APIs to find the ID of my stop so I can contruct the URL to get the info about arriving trains

http://reis.trafikanten.no/reisrest/realtime/getrealtimedata/3011510

Now to create a flow that will
  • use an inject to trigger a http request
  • pass the result to a JSON node that will convert to javascript
  • send the new payload to a javascript function that will select the first arriving train and determine how long until it arrives
  • if the time of the next train is less the 5 minutes, call an http request that will lift the bot's face
  • otherwise set it the bot back to rest

  • The Inject node can be configured to trigger on a schedule but I'll just do it manually for this demo.
  • "get arrival info" returns a pile of JSON which is passed through the json node and onto the javascript function.
  • The "find next arrival" has multiple outputs (described in the Node-RED docs) which allows it to send a true or a null to the http request nodes that will control the bot. A null wont trigger the request but any other value will.
  • If the train will arrive within 5 minutes then the http request to lift the bot face is triggered
  • The 3rd output sends the next train arrival time, plus the time difference in minutes to the debug node


(click img for the video)

Its not very clear with the video resolution, but you can see the debug messages show that while the time difference is over 5 mins, the bot keeps its face lowered. But once it arrival time is under 5 mins then it looks up.  You could easily make a fancier solution such as the bot running to the door when the train is nearby.

The nice part is how easy it is to wire everything together. The hardest part was the juggling of Date objects between javascript and JSON. Everything else took about 10 minutes. 

Next Steps

That's it. There are plenty of places to take this:

  • support sensor information from MOSS to Node-RED
  • create pre-configured Node-RED nodes for MOSS so that they are easier to integrate into flows
  • create a Node-RED app which communicates directly with the bluetooth block without going through the MOSS Scratch Extension
  • use sensors connected to an Arduino og RaspberryPi to control a moss-bot (or vice-versa)
  • etc, etc