Tank Control

Here is the basic interface for controlling the Tank robot from Nengo. It has four sensors (three proximity sensors and one grip sensor) and three motors (two tank treads and one claw).

To use this code, copy the "TankUDP" class into your code. It should work at the same time as the nengo_pushbot code.

import nengo
import nengo_pushbot
import time

import socket


class TankUDP(nengo.Node):
    def __init__(self, address, port, size_in, size_out, period=0.01):
        self.target = (address, port)
        self.period = period
        self.data = [0,0,0,0]
        self.last_time = None
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.socket.settimeout(0.01)

        super(TankUDP, self).__init__(output=self.send, size_in=size_in,
                                                          size_out=size_out)
    def send(self, t, x):
        now = time.time()
        if self.last_time is None or now > self.last_time + self.period:

            dead_zone = 0.05

            if -dead_zone < x[0] < dead_zone:
                left = 0
            elif x[0] >= 0:
                left = int(x[0]*120)
            else:
                left = int((-x[0])*120)+136

            if -dead_zone < x[1] < dead_zone:
                right = 0
            elif x[1] >= 0:
                right = int(x[1]*128)
            else:
                right = int((-x[1])*120)+136

            grip = 'close' if x[2] > 0.5 else 'open'

            msg = "%d,%d,%s" % (left, right, grip)
            #print 'send', msg
            self.socket.sendto(msg, self.target)
            try:
                data = self.socket.recv(2048)

                data = data.strip().split(',')

                max_sensor = 25.0
                if len(data) == 5:
                    p_r, p_c, p_l = float(data[1]), float(data[2]), float(data[3])
                    p_r = (max_sensor - min(max(p_r, 0), max_sensor))/max_sensor
                    p_c = (max_sensor - min(max(p_c, 0), max_sensor))/max_sensor
                    p_l = (max_sensor - min(max(p_l, 0), max_sensor))/max_sensor
                    grip = 1 if data[4]=='catch' else 0
                    self.data = [p_r, p_c, p_l, grip]
            except socket.error:
                print 'missed packet'

            self.last_time = now
        return self.data



model = nengo.Network(label='tank')
with model:
    tank = TankUDP(address='10.128.0.18', port=8889,
                  size_in=3, size_out=4, period=0.1)


    # left, centre, and right proximity sensors
    # 0 means no obstacle
    # 1 means very close obstacle
    proximity = nengo.Ensemble(300, 3, label='proximity')
    nengo.Connection(tank[:3], proximity)

    # grip sensors
    # 0 means nothing in the grip
    # 1 means holding something
    grip = nengo.Ensemble(100, 1, label='grip')
    nengo.Connection(tank[3], grip)


    # tank motor controls
    motor = nengo.Ensemble(200, 2, label='motor')
    nengo.Connection(motor, tank[[1,0]])

    # tank claw control
    claw = nengo.Ensemble(50, 1, label='claw')
    nengo.Connection(claw, tank[2])


    nengo.Connection(nengo.Node([0,0], label='in_motor'), motor)
    nengo.Connection(nengo.Node([0], label='in_claw'), claw)

    nengo.Probe(proximity)
    nengo.Probe(grip)