Tuesday 17 September 2013

Pi Bot Simulator

I decided to begin a new robot recently, but first I've decided to simulate one. Why? Well a good few reasons....
  • It's going to take some serious coding, and I wanted to make sure I was up to the task before spending time and money building it
  • Making digital tweaks to the design is easier than making them once its built
  • Programming on my nice shiny lap top is much easier than writing code and distributing it out to multiple raspberry pis while plugged into a robot!


So this'll divide up into a few areas which I'll detail here.

The Architecture

I'm writing the simulation in unity. Basically it involves:
  • A basic physical model of the robot, in a simple physical world.
  • Scripts to replicate the behaviors of the various components of the physical robot (i.e. a servo script that feeds input into a unity hinge joint).
  • A central script that runs a tcp server, and takes commands from external programs to communicate with the robot components.
This basic model is designed to simulate how the raspberry pis work in the actual robot. Each Pi is an external program that communicates with a subset of the robot components (or other raspberry pis).




This diagram shows a simplified model of what I have in mind, with only the motor and central controllers (ignoring the vision and speech processors). Crucially, the controller programs will be cross platform applications that run the same code on pc or raspberry pi. The only exception will be that the communications layer on a raspberry pi will be talking to physical devices like an IO board, wheras on a pc it'll be sending commands over TCP to unity.

A unity example

This snippet from my code shows the servo logic. It has a current position and target position, and uses them to control a damped spring on a hinge joint. The result is similar to the real world servo scenario, in which you send it a signal to tell it which position to move to.

using UnityEngine;
using System.Collections;

public class Servo : MonoBehaviour {
    
    public float Position;
    public float TargetPosition;
    
    // Use this for initialization
    void Start () {
        Application.runInBackground = true;
    }
    
    // Update is called once per frame
    void Update () {
    
    }
    
    float ConvertToWithinPI(float angle)
    {
        while(angle < -180) angle += 360;
        while(angle > 180) angle -= 360;
        return angle;
    }
    
    void FixedUpdate()
    {    
        float a = ConvertToWithinPI(ConvertToWithinPI(TargetPosition) - ConvertToWithinPI(Position));
        if(a < -5) a = -5;
        if(a > 5) a = 5;
        Position += a;
        
        JointSpring spring = hingeJoint.spring;
        spring.targetPosition = Position;
        hingeJoint.spring = spring;
    }
}


I've written similar scripts for motors, and a central one to wire them all together in which I'll add the tcp communications layer.

It in action

So without further coding ado, here's a video of it in action:


This first version is just me tinkering with the numbers in the unity editor. Here you can see me fiddling with the eyes, neck joints and wheel motors.

Next Time...

Next up, I'll get it so that the inputs and outputs to the various simulated devices can be accessed via a network connection. Once I'm there I'll be in a position to write applications in any language I like to control the various aspects of the robot (probably python for the low power stuff, and c++ for things like image processing).


No comments:

Post a Comment