class Move(object): """ Simple class used to represent a movement. This class simply wraps a sequence of positions of specified motors. The sequence must be recorded at a predefined frequency. This move can be recorded through the :class:`~pypot.primitive.move.MoveRecorder` class and played thanks to a :class:`~pypot.primitive.move.MovePlayer`. """ def __init__(self, freq): self._framerate = freq self._timed_positions = KDTreeDict() def __repr__(self): return '<Move framerate={} #keyframes={}>'.format(self.framerate, len(self.positions())) def __getitem__(self, i): return list(self._timed_positions.items())[i] @property def framerate(self): return self._framerate def add_position(self, pos, time): """ Add a new position to the movement sequence. Each position is typically stored as a dict of (time, (motor_name,motor_position)). """ self._timed_positions[time] = pos def iterpositions(self): """ Returns an iterator on the stored positions. """ return self._timed_positions.items() # return iter(self._timed_positions.items()) def positions(self): """ Returns a copy of the stored positions. """ return self._timed_positions # return list(self.iterpositions()) def save(self, file): """ Saves the :class:`~pypot.primitive.move.Move` to a json file. .. note:: The format used to store the :class:`~pypot.primitive.move.Move` is extremely verbose and should be obviously optimized for long moves. """ d = { 'framerate': self.framerate, 'positions': self._timed_positions, } json.dump(d, file, indent=2) @classmethod def load(cls, file): """ Loads a :class:`~pypot.primitive.move.Move` from a json file. """ d = json.load(file) move = cls(d['framerate']) move._timed_positions.update(d['positions']) return move
class Move(object): """ Simple class used to represent a movement. This class simply wraps a sequence of positions of specified motors. The sequence must be recorded at a predefined frequency. This move can be recorded through the :class:`~pypot.primitive.move.MoveRecorder` class and played thanks to a :class:`~pypot.primitive.move.MovePlayer`. """ def __init__(self, freq): self._framerate = freq self._timed_positions = KDTreeDict() def __repr__(self): return '<Move framerate={} #keyframes={}>'.format( self.framerate, len(self.positions())) def __getitem__(self, i): return list(self._timed_positions.items())[i] @property def framerate(self): return self._framerate def add_position(self, pos, time): """ Add a new position to the movement sequence. Each position is typically stored as a dict of (time, (motor_name,motor_position)). """ self._timed_positions[time] = pos def iterpositions(self): """ Returns an iterator on the stored positions. """ return self._timed_positions.items() def positions(self): """ Returns a copy of the stored positions. """ return self._timed_positions def plot(self, ax): pos = self.positions() if not pos: return motors = pos[0].keys() n = len(pos) t = np.linspace(0, n / self.framerate, n) pos = self.positions() p = {} for name in motors: p[name] = [] for tt in t: for k, v in pos[float(tt)].items(): p[k].append(v[0]) for name in motors: ax.plot(t, p[name]) ax.legend(motors) ax.set_xlabel('Time (in s)') ax.set_ylabel('Position (in degree)') def save(self, file): """ Saves the :class:`~pypot.primitive.move.Move` to a json file. .. note:: The format used to store the :class:`~pypot.primitive.move.Move` is extremely verbose and should be obviously optimized for long moves. """ d = { 'framerate': self.framerate, 'positions': self._timed_positions, } json.dump(d, file, indent=2) @classmethod def create(cls, d): """ Create a :class:`~pypot.primitive.move.Move` from a dictionary. """ move = cls(d['framerate']) move._timed_positions.update(d['positions']) return move @classmethod def load(cls, file): """ Loads a :class:`~pypot.primitive.move.Move` from a json file. """ d = json.load(file) return cls.create(d) @classmethod def loads(cls, str): """ Loads a :class:`~pypot.primitive.move.Move` from a json string. """ d = json.loads(str) return cls.create(d)
class Move(object): """ Simple class used to represent a movement. This class simply wraps a sequence of positions of specified motors. The sequence must be recorded at a predefined frequency. This move can be recorded through the :class:`~pypot.primitive.move.MoveRecorder` class and played thanks to a :class:`~pypot.primitive.move.MovePlayer`. """ def __init__(self, freq): self._framerate = freq self._timed_positions = KDTreeDict() def __repr__(self): return '<Move framerate={} #keyframes={}>'.format(self.framerate, len(self.positions())) def __getitem__(self, i): return list(self._timed_positions.items())[i] @property def framerate(self): return self._framerate def add_position(self, pos, time): """ Add a new position to the movement sequence. Each position is typically stored as a dict of (time, (motor_name,motor_position)). """ self._timed_positions[time] = pos def iterpositions(self): """ Returns an iterator on the stored positions. """ return self._timed_positions.items() def positions(self): """ Returns a copy of the stored positions. """ return self._timed_positions def plot(self, ax): pos = self.positions() if not pos: return motors = pos[0].keys() n = len(pos) t = np.linspace(0, n / self.framerate, n) pos = self.positions() p = {} for name in motors: p[name] = [] for tt in t: for k, v in pos[float(tt)].items(): p[k].append(v[0]) for name in motors: ax.plot(t, p[name]) ax.legend(motors) ax.set_xlabel('Time (in s)') ax.set_ylabel('Position (in degree)') def save(self, file): """ Saves the :class:`~pypot.primitive.move.Move` to a json file. .. note:: The format used to store the :class:`~pypot.primitive.move.Move` is extremely verbose and should be obviously optimized for long moves. """ d = { 'framerate': self.framerate, 'positions': self._timed_positions, } json.dump(d, file, indent=2) @classmethod def create(cls, d): """ Create a :class:`~pypot.primitive.move.Move` from a dictionary. """ move = cls(d['framerate']) move._timed_positions.update(d['positions']) return move @classmethod def load(cls, file): """ Loads a :class:`~pypot.primitive.move.Move` from a json file. """ d = json.load(file) return cls.create(d) @classmethod def loads(cls, str): """ Loads a :class:`~pypot.primitive.move.Move` from a json string. """ d = json.loads(str) return cls.create(d)