Source code for kf.path

"""Path generator objects for simulating low-level motion control.
"""
################################################################
# Written in 2018-2019 by Garth Zeglin <garthz@cmu.edu>

# To the extent possible under law, the author has dedicated all copyright
# and related and neighboring rights to this software to the public domain
# worldwide. This software is distributed without any warranty.

# You should have received a copy of the CC0 Public Domain Dedication along with this software.
# If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.

################################################################
# standard Python libraries
import math

################################################################
[docs]class Path(object): """Representation of the current path generator for a single winch. This keeps the physical calculations separate from the graphics. This reimplements the functionality of Path.h and Path.cpp in the StepperWinch Arduino sketch. The model is based on a second-order simple harmonic oscillator. The command API should be kept compatible with the winch interface class which transmits commands over a serial port to an Arduino-based winch. """ def __init__(self): # Model based on StepperWinch/Path. Units are 800 steps/rev. self.q = 0.0 # current model position, in dimensionless units (e.g. step or encoder counts) self.qd = 0.0 # current model velocity in units/sec self.qdd = 0.0 # current model acceleration, in units/sec/sec self.q_d = 0.0 # current model target position in dimensionless units self.qd_d = 0.0 # current model target velocity in dimensionless units/sec self.t = 0.0 # elapsed model time, in seconds self.k = 4*math.pi*math.pi # proportional feedback gain, in (units/sec/sec)/(units), which is (1/sec^2) self.b = 1.0 # derivative feedback gain, in (units/sec/sec)/(units/sec), which is (1/sec) self.qd_max = 3500.0 # maximum allowable speed in units/sec self.qdd_max = 35000.0 # maximum allowable acceleration in units/sec/sec return
[docs] def update_for_interval(self, interval): """Run the simulator for the given interval, which may include one or more integration steps.""" while interval > 0.0: dt = min(interval, 0.005) interval -= dt self.step(dt)
[docs] def step(self, dt): # Model based on StepperWinch/Path. Units are 800 steps/rev. # calculate the derivatives self.qdd = self.k * (self.q_d - self.q) + self.b * (self.qd_d - self.qd) # clamp the acceleration within range for safety self.qdd = min(self.qdd_max, max(self.qdd, -self.qdd_max)) # integrate one time step self.q += self.qd * dt self.qd += self.qdd * dt self.q_d += self.qd_d * dt # integrate the target velocity into the target position self.t += dt # clamp the model velocity within range for safety self.qd = min(self.qd_max, max(self.qd, -self.qd_max)) return
#------------------------------------------------------------------------------ # The command API follows which mimics the interface to the actual winches.
[docs] def set_target(self, position): """Set the absolute target position in dimensionless units.""" self.q_d = position return
[docs] def increment_target(self, offset): """Add a signed offset to the target position. The units are dimensionless 'steps'. If using a microstepping driver, these may be less than a physical motor step. """ self.q_d += offset return
[docs] def set_velocity(self, velocity): """Set the constant velocity of the target in units/sec""" self.qd_d = velocity return
[docs] def set_freq_damping(self, freq, damping): """Convenience function to set second order model gains in terms of natural frequency and damping ratio. The frequency is in Hz, the damping ratio is 1.0 at critical damping. """ self.k = freq * freq * 4 * math.pi * math.pi self.b = 2 * math.sqrt(self.k) * damping return
################################################################