# 3.27. Teaching a Robot to Move¶

First, we have a neural network watch a teacher. The robot starts at the end of a hallway, and approaches a target location 1 meter from the end of the hall.

In [1]:
from conx import *
from jyro.simulator import *
import math
import time
Using Theano backend.
conx, version 3.5.2
In [2]:
def make_world(physics):
physics.addBox(0, 0, 8, 2, fill="backgroundgreen", wallcolor="gray")

def make_robot():
robot = Pioneer("Pioneer", 7.5, 1, math.pi/2) #parameters are x, y, heading (in radians)
return robot
In [3]:
robot = make_robot()
robot
Out[3]:
In [4]:
def collect_data(simulator):
data = []
simulator.reset() # put robot back to where it is defined
while True:
scaled_dist = simulator.robot["sonar"].getData()[0]/6.0
power = 1.0 - ((1 - scaled_dist)/0.33 * 0.9) # 1.0 to 0.7, power 1.0 to 0
robot.move(power, 0)
data.append([scaled_dist, [power]])
simulator.step()
time.sleep(.1) # don't overwhelm the network
if power < 0.05:
break
return data
In [5]:
sim = VSimulator(robot, make_world, size=(700, 180))
In [6]:
data = collect_data(sim)
In [7]:
len(data)
Out[7]:
81
In [8]:
train = ["Training Data", [pair[1][0] for pair in data]]
In [9]:
plot(train,
title="Speed as a Function of Distance",
xlabel="distance from target",
ylabel="speed",
xs=[pair[0] for pair in data], default_symbol="o")
In [10]:
net = Network("Go To Target")
net.connect()
net.compile(loss="mse", optimizer=SGD(lr=.1, momentum=.5))
net.model.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
input (InputLayer)           (None, 1)                 0
_________________________________________________________________
hidden (Dense)               (None, 10)                20
_________________________________________________________________
output (Dense)               (None, 1)                 11
=================================================================
Total params: 31
Trainable params: 31
Non-trainable params: 0
_________________________________________________________________
In [11]:
net.dataset.summary()
Input Summary:
count  : 81 (81 for training, 0 for testing)
shape  : [()]
range  : (0.6511592, 1.0)
Target Summary:
count  : 81 (81 for training, 0 for testing)
shape  : [(1,)]
range  : (0.048616093, 1.0)
In [12]:
net.dashboard()
In [13]:
if net.saved():
net.plot_loss_acc()
else:
net.train(400, accuracy=1.0, tolerance=0.05, batch_size=1, save=True, plot=True)
In [14]:
test = ["Network", [net.propagate(pair[0], visualize=False)[0] for pair in data]]
In [15]:
plot([train, test],
title="Speed as a Function of Distance",
xlabel="distance from target",
ylabel="speed",
default_symbol="o",
xs=[pair[0] for pair in data])

# 3.28. Network-Controlled Robot¶

In [16]:
outputs = []

def net_brain(robot):
scaled_distance = robot["sonar"].getData()[0]/6
output = net.propagate([scaled_distance], visualize=False)[0]
robot.move(output, 0)
outputs.append([scaled_distance, output])

robot.brain = net_brain
In [17]:
sim.widget

Run the experiment above before continuing:

1. press the refresh button to put robot back into initial position
2. press the play button until robot get’s to target position
3. press stop
4. move robot to new position
5. press play to see what happens
6. press stop
In [18]:
trained_range = ["Net in Trained Range", [pair for pair in outputs if pair[0] > .66]]
In [19]:
scatter(trained_range,
title="Network Generalization", xlabel="input", ylabel="output", default_symbol="o")
In [22]:
untrained_range = ["Net out of Trained Range", [pair for pair in outputs if pair[0] < .66]]
In [23]:
scatter([trained_range, untrained_range],
title="Network Generalization", xlabel="input", ylabel="output", default_symbol="o")