How-To: Control a Poppy Creature using Snap!

Introduction

This notebook will describe how:

  • you can connect the visual programming language Snap! to a Poppy Creature
  • and how you can control it in real time using our basic custom blocks.

Snap! is a "very powerful visual, drag-and-drop programming language. It is an extended reimplementation of Scratch (a project of the Lifelong Kindergarten Group at the MIT Media Lab) that allows you to Build Your Own Blocks". It is an extremely efficient tool to learn how to program for kids or even college students and also a powerful prototyping method for artists.

Snap! is open-source and it is entirelly written in javascript, you only need a browser connected to the Poppy Creature webserver. No installation is required on the client side!

Note: We assume in this tutorial that you are familiar with the basic of Snap! or Scratch. If it's not the case you can find a lot of documentation online. We especially recommand the very good Snap! reference manual.

An example of the Snap! interface:

What's needed

To follow this tutorial you will need:

  • the python pypot library version >= 2.1
  • a poppy creature (real or simulated)

Note: for this notebook we will use a simulated poppy humanoid in V-REP (see this notebook for details on how they can be installed and connected) but you can use any other creature (e.g. a real poppy ergo for instance). Only the configuration of the robot host will change (see details below).

Connect Snap! to a Poppy Creature

To connect Snap! with a Poppy Creature two steps are required:

  • create a webserver which allows Snap! to get/post values from/to a Poppy Creature through pypot REST API. Then we use the http block to connect Snap! with the robot (you can refer to the section The Outside World from Snap! reference manual for more details).
  • connect to Snap! locally or online and import the Poppy specific blocks.

So, first we will create and launch the Robot Snap Server. In more details, we will:

We create a Poppy Humanoid using the approach discribed in here:


In [1]:
from poppy.creatures import PoppyHumanoid

poppy = PoppyHumanoid(simulator='vrep')

Then we just need to instantiate the SnapRobotServer class and attach it to the robot.

You have to manually specify the host and port to which the server will be attached. Here, we will bind it to the localhost for simplicity. Yet, this will not allow for external connections. You can use host='0.0.0.0' to automatically attach the webserver to the IP of your machine. Hostnames can also be used, for instance Poppy Creatures usually provide an hostname such as host='poppy-humanoid.local'.


In [2]:
from pypot.server.snap import SnapRobotServer

snap_server = SnapRobotServer(poppy, host='127.0.0.1', port=8080)
snap_server.run()

Note: the run method will run the server forever and thus block the main thread. This is here not a problem as the server part of the tutorial is done. If you need to run other python code after, you can run the SnapRobotServer inside a thread.

Run Snap!

Now that we have started a webserver attached to our Poppy Creature, we just need to run Snap! on a web browser.

As stated above, Snap! is entirelly written in javascript and thus the only things needed to run it is a (not too old) web browser! You can run Snap! in two modes:

We will now detail on you can control your Poppy Creature via the two approaches:

Note that the online one is more straightforward and should thus be privileged except if you do not have an internet connection.

Alternative 1: Run Snap! Online

The last step required before actually making your robot moves in Snap! is to import our predefined blocks. Snap! provides a really simple way to do that: you just have to go to this url: http://snap.berkeley.edu/snapsource/snap.html#open:http://127.0.0.1:8080/snap-blocks.xml

Note the #open:http://... at the end of the url. It tells Snap! to automatically loads the found at the url: http://127.0.0.1:8080/snap-blocks.xml.

Note: if you changed the web server host, you need to change it in here as well. For instance if you use the Poppy Ergo default hostname you need to go to http://snap.berkeley.edu/snapsource/snap.html#open:http://poppy-ergo.local:8080/snap-blocks.xml instead.

You should now see something like this in your browser (note importing the blocks may take a few seconds):

Alternative 2: Run Snap! locally

If you use Snap! locally instead, you will have to first:

  • launch Snap! by opening the snap.html file from you snap local folder
  • import the project with our specific blocks via the snap menu

Our blocks can be found in the pypot folder (its location will depend on your operating system and how you installed it). You can use python to find it:

For instance, on my machine:


In [3]:
import os
import pypot

os.path.join(os.path.dirname(pypot.__file__), 'server', 'pypot-snap-blocks.xml')


Out[3]:
'/Users/pierrerouanet/dev/pypot/pypot/server/pypot-snap-blocks.xml'

Alternatively you can directly download it from the github repository. For instance:

wget https://raw.githubusercontent.com/poppy-project/pypot/master/pypot/server/pypot-snap-blocks.xml

Once imported you should see somrthing like:

Using Snap! to make your Poppy Creature moves

You can see that our base project comes with a few specific blocks such as:

Those blocks can be used to respectively:

  • get a list of all motors name
  • get the value of a register motor (e.g. get motor "head_z" register "present_load")
  • get a motor present position
  • turn a motor compliant or not
  • set a new motor goal position

Other blocks are also available. Their behavior should be easily deduced from their name.

Position synchronisation loop

For performance issue, we add extra blocks which retrieve and set the position for all motors all the time. Thus, each motor does not have to send its new position value but they are all sent at the same time. This is only helpfull if you try to control several motors at a rather high frequency (more than a few Hz).

This synchronization loop can be seen here:

Note that you may have to change the host to the one you choose for your webserver - e.g. poppy-ergo.local in the first block.

If you clik on the green flag, all your motors should now be synchronized and you can start setting new positions. By clicking on the left blocks, you should make the robot turns its head by 30°.

Control a motor via a Snap! slider

To control a motor via a slider you need to:

  • first, make a variable - we will call it head position
  • right click on it and use the slider option
  • change the slider min/max to (-50, 50)

Then, connect it to a motor:

  • use the set motor goal position block
  • put it inside a forever loop
  • add a wait for performance issue

Apply a sinus on a few motors

Demonstration Video