Example #1
0
class CTSLIP_xst(csync.FlexSOD):
    "Extended state -- includes auxvars"
    Fields = (['t'] + csync.getFields(SRC, "CTSLIP_state", 2) +
              csync.getFields(SRC, "CTSLIP_aux", 2))
    assert len(Fields) == FASTODE_CTSLIP.WIDTH

    def upd_dbg(self, name, val):
        print "UPD called"

    def cfgFromParam(self, pars):
        self.vis_R = pars.len0 / 5
        self.vis_W = self.vis_R * 0.75
        self.vis_ofs = pars.stOfs
        if abs(pars.stHalfSweep - pars.stHalfDuty) > 0.02:
            self.vis_swp = pars.stHalfSweep
        else:
            self.vis_swp = 0
        self.domain = int(pars.domain)

    def plot(self):
        X = self.com_x
        Z = self.com_z + self.zOfs
        l = plotCircle(X, Z, self.vis_R, 36, color='k', linewidth=2)
        if self.vis_swp:
            l.append(
                plotCircle(X,
                           Z,
                           self.vis_R,
                           18,
                           arc=(self.vis_ofs - self.vis_swp,
                                self.vis_ofs + self.vis_swp),
                           color=[0.6, 0.9, 0.6],
                           linewidth=5))
        l.append(
            plot([X, X + self.vis_R * 1.6 * cos(self.clk)],
                 [Z, Z + self.vis_R * 1.6 * sin(self.clk)],
                 color='m',
                 linewidth=2))
        for leg in xrange(2):
            lx = getattr(self, "leg_x_%d" % leg)
            lz = getattr(self, "leg_z_%d" % leg)
            rx = getattr(self, "ref_x_%d" % leg)
            rz = getattr(self, "ref_z_%d" % leg)
            lc = 'brgmck'[leg]
            l.append(plot([X + rx], [Z + rz], 'd' + lc))
            lkw = {'color': lc, 'linewidth': 2}
            if self.domain & (1 << leg):
                l.extend(
                    plotZigZag(X + lx * 0.2, Z + lz * 0.2, X + lx * 0.8, Z +
                               lz * 0.8, self.vis_W, 7, **lkw) +
                    plot([X, X + lx * 0.2], [Z, Z + lz * 0.2], **lkw) +
                    plot([X + lx * 0.8, X + lx], [Z + lz * 0.8, Z +
                                                  lz], **lkw) +
                    plot([X + lx], [Z + lz], '^' + lc))
            else:
                l.extend(
                    plot([X, X + lx], [Z, Z + lz], '-', **lkw)
                    #+plot( [X+lx], [Z+lz], 'o'+lc )
                )
        return l
Example #2
0
class CTSLIP_param(csync.FlexSOD):
    Fields = csync.getFields(SRC, "CTSLIP_param", 2)
    assert len(Fields) == FASTODE_CTSLIP.NPAR

    def upd20_stWn(self, nm, val):
        self.stK = val * val
        self.stMu = self.stZeta * 2 * val
        print "[upd] set stK, stMu from stWn, stZeta"

    def upd09_hexed(self, nm, val):
        tc, dc, phs, ph0, Kp, Kd = val
        # Omega is 2*pi/(time-of-cycle), but direction is negative!
        self.omega = -2 * pi / tc
        # Our duty cycle is in radians
        self.stHalfDuty = dc * pi
        # Sweep angle is the same
        self.stHalfSweep = phs / 2.0
        # Zero angle is "down" for hexed data
        self.stOfs = ph0 - pi / 2
        # Proportional FB is just like the torsional stiffness
        #   NOTE: for small changes; we use sin(delta) in the eqn
        self.tqKth = Kp
        # Given warning if a nonzero Kd is requested
        if Kd != 0:
            print "[upd] WARNING: Kd=%g requested by Kd not supported" % Kd
        print "[upd] applied hextuple ", repr(val)

    def upd10_stDecayFrac(self, nm, val):
        # arc subtended by decay time
        ang = val * self.stHalfDuty
        # Natural frequency must finish arc in time
        self.stWn = abs(self.omega) * (2 * pi / ang)
        print "[upd] set stWn from stDecayFrac"

    def upd90_stHalfDuty(self, nm, val):
        if val < 0 or val > pi:
            raise ValueError, "Half duty cycle range is 0..PI"
        if val == 0 or val == pi:
            self.stHalfDuty += 1e-99
            print "[upd] fixed invalid stHalfDuty -- don't use 0 and PI!"

    def copy(self):
        return COPY(self)
Example #3
0
class CTSLIP_state(csync.FlexSOD):
    Fields = ['t'] + csync.getFields(SRC, "CTSLIP_state", 2)
    assert len(Fields) == FASTODE_CTSLIP.DIM + 1

    def upd50_par(self, nm, val):
        if not hasattr(val, 'clkTD') or val.clkTD is None:
            return
        if val.gravityZ >= 0:
            return
        # Estimate time 'till touchdown
        t2td = sqrt(2 * self.com_z / -val.gravityZ)
        # Create clk IC that cancels phase change while falling
        self.clk = val.clkTD - t2td * val.omega
        print "[upd] fixed initial clk for clkTD"

    def upd90_mdl(self, nm, val):
        x = CTSLIP_aux()
        y0 = numpy.concatenate((self[:], zeros(len(x))))
        val.computeAux(y0)
        x.fromArray(y0[len(self):])
        # If leg 0 is on COM --> move to ref
        if self.leg_z_0 == 0 and self.leg_x_0 == 0:
            self.leg_x_0 = x.ref_x_0
            self.leg_z_0 = x.ref_z_0
            print "[upd] Locked initial leg 0 position to reference"
        # if a penetrating stance --> fix it
        if self.com_z + self.leg_z_0 < 0:
            self.leg_x_0 *= abs(self.com_z) / abs(self.leg_z_0)
            self.leg_z_0 = -self.com_z
            print "[upd] Initial leg 0 moved to Z=0"
        # If leg 1 is on COM --> move to ref
        if self.leg_z_1 == 0 and self.leg_x_1 == 0:
            self.leg_x_1 = x.ref_x_1
            self.leg_z_1 = x.ref_z_1
            print "[upd] Locked initial leg 1 position to reference"
        # if a penetrating stance --> fix it
        if self.com_z + self.leg_z_0 < 1:
            self.leg_x_1 *= abs(self.com_z) / abs(self.leg_z_1)
            self.leg_z_1 = -self.com_z
            print "[upd] Initial leg 1 moved to Z=0"
        return

    def upd50_plane(self, nm, coef):
        """
    dot([1,state],coef)-val is the event function
    coef -- len<5 -- (val, co_clk, co_vx, co_z, co_vz, co_x), zeros appended
    """
        coef = array((list(coef) + [0] * 6)[:6], float)
        if not any(coef):
            coef[0] = 1000
            print "[upd] plane event disabled"
        else:
            p = self.par
            (p.co_value, p.co_clk, p.co_com_vx, p.co_com_z, p.co_com_vz,
             p.co_com_x) = coef
            print "[upd] plane is ", coef

    def getPlane(self):
        p = self.par
        return array(
            [p.co_clk, p.co_com_vx, p.co_com_z, p.co_com_vz, p.co_com_x])

    def planeVal(self, dat):
        p = self.par
        co = self.getPlane()
        dat = asarray(dat)
        if dat.shape[-1] != len(co):
            s = CTSLIP_xst()
            dat = dat[..., [s.clk, s.com_vx, s.com_z, s.com_vz, s.com_x]]
        return dot(dat, co) + p.co_value

    def copy(self):
        res = COPY(self)
        if hasattr(res, 'par'):
            res.par = res.par.copy()
        return res
Example #4
0
class CTSLIP_events(csync.FlexSOD):
    Fields = csync.getFields(SRC, "CTSLIP_events", 2)
Example #5
0
class CTSLIP_aux(csync.FlexSOD):
    Fields = csync.getFields(SRC, "CTSLIP_aux", 2)
    assert len(Fields) == FASTODE_CTSLIP.AUX