The goal of this notebook is to help you identify the performance of your robot and where the bottle necks are. We will measure:
from ipywidgets import interact
%pylab inline
Populating the interactive namespace from numpy and matplotlib
All bench info will be stored in this dictionary so it's easy to compare with other platforms.
results = {}
import platform
p = platform.platform()
print(p)
results['platform'] = p
Linux-4.19.118-v7l+-armv7l-with-debian-10.4
import sys
v = sys.version
print(v)
results['python'] = v
3.7.3 (default, Dec 20 2019, 18:57:59) [GCC 8.3.0]
import pypot
results['pypot'] = pypot.__version__
print('Pypot version: {}'.format(results['pypot']))
Pypot version: 4.0.0
from pypot.creatures import installed_poppy_creatures
RobotCls = None
def robot_selector(robot):
global RobotCls
RobotCls = robot
interact(robot_selector, robot=installed_poppy_creatures);
interactive(children=(Dropdown(description='robot', options={'poppy-ergo-jr': <class 'poppy_ergo_jr.poppy_ergo…
RobotCls
poppy_ergo_jr.poppy_ergo_jr.PoppyErgoJr
robot = RobotCls()
results['robot'] = RobotCls
Make sure all motors are turned off to avoid breaking anything:
for m in robot.motors:
m.compliant = True
We find the synchronization loop for pos/speed/load and monkey patch them for monitoring.
import time
from pypot.dynamixel.syncloop import MetaDxlController
from pypot.dynamixel.controller import PosSpeedLoadDxlController
meta_controllers = [c for c in robot._controllers if isinstance(c, MetaDxlController)]
#controllers = [cc for cc in c.controllers for c in meta_controllers if isinstance(cc, PosSpeedLoadDxlController)]
controllers = []
for c in meta_controllers:
controllers.extend([cc for cc in c.controllers if isinstance(cc, PosSpeedLoadDxlController)])
for c in controllers:
c.stop()
for c in controllers:
def wrapped_update():
if not hasattr(c, 't'):
c.t = []
c.t.append(time.time())
c.update()
c._update = wrapped_update
for c in controllers:
c.start()
Now, we define our monitor and plotting functions.
import psutil
def monitor(controllers, duration):
for c in controllers:
c.stop()
c.t = []
c.start()
cpu = []
start = time.time()
while time.time() - start < duration:
time.sleep(1.0)
cpu.append(psutil.cpu_percent())
print('Avg CPU usage: {}%'.format(mean(cpu)))
return {c: array(c.t) for c in controllers}
def freq_plot(logs):
for c, t in logs.items():
dt = diff(t)
freq = 1.0 / dt
print('Avg frq for controller {}: {:.3f} ms STD={:.3} ms'.format(c.ids, freq.mean(), freq.std()))
hist(freq)
xlim(0, 100)
We also define this follow trajectory function, which applies a sinus on one motor (choosen below) and plot how close is its real position from the target one:
def follow_trajectory(motor, duration=5, freq=50):
t = linspace(0, duration, duration * freq)
a1, f1 = 10.0, 1.0
a2, f2 = 5.0, 0.5
traj = a1 * sin(2 * pi * f1 * t) + a2 * sin(2 * pi * f2 * t)
rec = []
motor.compliant = False
motor.moving_speed = 0
motor.goal_position = 0
time.sleep(1.)
for p in traj:
motor.goal_position = p
rec.append(motor.present_position)
time.sleep(1.0 / freq)
motor.compliant = True
plot(traj)
plot(rec)
Now choose which motor you want to use for the follow trajectory test. It should be able to move freely from -20 to +20 degrees.
motor = None
def motor_selector(m):
global motor
motor = getattr(robot, m)
interact(motor_selector, m=[m.name for m in robot.motors]);
interactive(children=(Dropdown(description='m', options=('m1', 'm2', 'm3', 'm4', 'm5', 'm6'), value='m1'), Out…
Our benchmark duration in seconds:
duration = 30
d = monitor(controllers, duration)
freq_plot(d)
results['normal'] = d
Avg CPU usage: 10.7% Avg frq for controller [1, 2, 3, 4, 5, 6]: 49.264 ms STD=2.85 ms
follow_trajectory(motor)
for p in robot.primitives:
p.stop()
robot._primitive_manager.stop()
d = monitor(controllers, duration)
freq_plot(d)
results['without primitive'] = d
Avg CPU usage: 11.7% Avg frq for controller [1, 2, 3, 4, 5, 6]: 49.283 ms STD=2.95 ms
follow_trajectory(motor)
for s in robot.sensors:
s.close()
d = monitor(controllers, duration)
freq_plot(d)
results['without sensor'] = d
Avg CPU usage: 6.0% Avg frq for controller [1, 2, 3, 4, 5, 6]: 49.729 ms STD=0.118 ms
follow_trajectory(motor)