Beispiel #1
0
    def __init__(self, args, motor_entry):

        self.hijoint = NeckKinematics.upper_neck()
        self.lojoint = NeckKinematics.lower_neck()

        # XXX TODO remove hard-coded physical dimensions
        # Han neck mechanism has the upper joint being 8.93 centimeters
        # in front of the lower joint, and 112.16 centimeters above it.
        self.kappa = math.atan2(8.93, 112.16)

        # Returns the upper-neck left motor position, in radians
        def get_upper_left(q):
            (phi, theta, psi) = quat_to_asa(q)
            try:
                self.hijoint.inverse_kinematics(theta, phi)
            except OverflowError:
                print "Upper left motor jam", theta, phi
            # print "Upper motors:", self.hijoint.theta_l, self.hijoint.theta_r
            return self.hijoint.theta_l

        # Returns the upper-neck right motor position, in radians
        def get_upper_right(q):
            (phi, theta, psi) = quat_to_asa(q)
            try:
                self.hijoint.inverse_kinematics(theta, phi)
            except OverflowError:
                print "Upper right motor jam", theta, phi
            return self.hijoint.theta_r

        # Returns the lower-neck left motor position, in radians
        def get_lower_left(q):
            (phi, theta, psi) = quat_to_asa(q)
            # (phi, theta, eta) = NeckVertical.neck_cant(phi, theta, psi, self.kappa)
            try:
                self.lojoint.inverse_kinematics(theta, phi)
            except OverflowError:
                print "Lower left motor jam", theta, phi
            # print "Lower motors:", self.lojoint.theta_l, self.lojoint.theta_r
            return self.lojoint.theta_l

        # Returns the lower-neck right motor position, in radians
        def get_lower_right(q):
            (phi, theta, psi) = quat_to_asa(q)
            # (phi, theta, eta) = NeckVertical.neck_cant(phi, theta, psi, self.kappa)
            # print "Lower theta-phi:", theta, phi
            try:
                self.lojoint.inverse_kinematics(theta, phi)
            except OverflowError:
                print "Lower right motor jam", theta, phi
            return self.lojoint.theta_r

        # Yaw (spin about neck-skull) axis, in radians, right hand rule.
        def get_yaw(q):
            (phi, theta, psi) = quat_to_asa(q)

            # XXX TODO The neck cant produces a small correction to the yaw,
            # the formulas are there in neck_cant, but need to be integrated
            # here...

            # The byaw is a "crude" approximation to the correct yaw ...
            # but in fact, the worst-case error is about half a percent,
            # and usually much much better (less than 1/20th of a percent)
            byaw = psi + phi
            if 3.1415926 < byaw:
                byaw -= 2 * 3.14159265358979

            return byaw

        funcs = {
            'upleft': lambda q: get_upper_left(q),
            'upright': lambda q: get_upper_right(q),
            'loleft': lambda q: get_lower_left(q),
            'loright': lambda q: get_lower_right(q),
            'yaw': lambda q: get_yaw(q)
        }
        self.map = funcs[args['axis'].lower()]
Beispiel #2
0
    def __init__(self, args, motor_entry):

        self.hijoint = NeckKinematics.upper_neck()
        self.lojoint = NeckKinematics.lower_neck()

        # split the angles in two, giving sume to the upper and some to the
        # lower ujoint. Valid values for split are -1.0 to 2.0, with a
        # 50%-50% given by setting split to 0.5.
        # Setting upper_split to 1.0 should result in exactly the same
        # behavior as the Quaternion2Upper class above.
        self.upper_split = 0.5
        self.lower_split = 1.0 - self.upper_split

        # XXX TODO remove hard-coded physical dimensions
        # Han neck mechanism has the upper joint being 8.93 centimeters
        # in front of the lower joint, and 112.16 centimeters above it.
        self.kappa = math.atan2(8.93, 112.16)

        # Returns the upper-neck left motor position, in radians
        def get_upper_left(q):
            fq = quat_fraction(q, self.upper_split)
            (phi, theta, psi) = quat_to_asa(fq)
            self.hijoint.inverse_kinematics(theta, phi)
            # print "Upper theta-phi:", theta, phi
            # print "Upper motors:", self.hijoint.theta_l, self.hijoint.theta_r
            return self.hijoint.theta_l

        # Returns the upper-neck right motor position, in radians
        def get_upper_right(q):
            fq = quat_fraction(q, self.upper_split)
            (phi, theta, psi) = quat_to_asa(fq)
            self.hijoint.inverse_kinematics(theta, phi)
            return self.hijoint.theta_r

        # Returns the lower-neck left motor position, in radians
        def get_lower_left(q):
            fq = quat_fraction(q, self.lower_split)
            (phi, theta, psi) = quat_to_asa(fq)
            # (phi, theta, eta) = NeckVertical.neck_cant(phi, theta, psi, self.kappa)
            self.lojoint.inverse_kinematics(theta, phi)
            # print "Lower theta-phi:", theta, phi
            # print "Lower motors:", self.lojoint.theta_l, self.lojoint.theta_r
            return self.lojoint.theta_l

        # Returns the lower-neck right motor position, in radians
        def get_lower_right(q):
            fq = quat_fraction(q, self.lower_split)
            (phi, theta, psi) = quat_to_asa(fq)
            # (phi, theta, eta) = NeckVertical.neck_cant(phi, theta, psi, self.kappa)
            self.lojoint.inverse_kinematics(theta, phi)
            return self.lojoint.theta_r

        # Yaw (spin about neck-skull) axis, in radians, right hand rule.
        def get_yaw(q):
            (phi, theta, psi) = quat_to_asa(q)

            # XXX TODO The neck cant produces a small correction to the yaw,
            # the formulas are there in neck_cant, but need to be integrated
            # here...

            # The byaw is a "crude" approximation to the correct yaw ...
            # but in fact, the worst-case error is about half a percent,
            # and usually much much better (less than 1/20th of a percent)
            byaw = psi + phi
            if 3.1415926 < byaw:
                byaw -= 2 * 3.14159265358979

            return byaw

        funcs = {
            'upleft': lambda q: get_upper_left(q),
            'upright': lambda q: get_upper_right(q),
            'loleft': lambda q: get_lower_left(q),
            'loright': lambda q: get_lower_right(q),
            'yaw': lambda q: get_yaw(q)
        }
        self.map = funcs[args['axis'].lower()]
Beispiel #3
0
    def __init__(self, args, motor_entry):

        self.hijoint = NeckKinematics.upper_neck()
        self.worst = 0

        # Returns the upper-neck left motor position, in radians
        def get_upper_left(q):
            (phi, theta, psi) = quat_to_asa(q)
            self.hijoint.inverse_kinematics(theta, phi)
            # print "Motors: left right", self.hijoint.theta_l, self.hijoint.theta_r
            return self.hijoint.theta_l

        # Returns the upper-neck right motor position, in radians
        def get_upper_right(q):
            (phi, theta, psi) = quat_to_asa(q)
            self.hijoint.inverse_kinematics(theta, phi)
            return self.hijoint.theta_r

        # Yaw (spin about neck-skull) axis, in radians, right hand rule.
        def get_yaw(q):
            (phi, theta, psi) = quat_to_asa(q)

            # The twist factor is the actual correction for the fact
            # that the gimbal in the neck assembly prevents the u-joint
            # from rotating.
            twist = math.atan2(math.tan(phi), math.cos(theta))
            if twist < 0:
                twist += 3.14159265358979

            # The actual neck yaw.
            yaw = psi + twist
            if 3.1415926 < yaw:
                yaw -= 2 * 3.14159265358979

            # The bad_yaw is a "crude" approximation to the correct yaw ...
            # but in fact, the worst-case error is about half a percent,
            # and usually much much better (less than 1/20th of a percent)
            bad_yaw = psi + phi
            if 3.1415926 < bad_yaw:
                bad_yaw -= 2 * 3.14159265358979

            # Hacky corrections to bad quadrant of the arctan...
            if 2 < yaw - bad_yaw:
                yaw -= 3.14159265358979
            if yaw - bad_yaw < -2:
                yaw += 3.14159265358979

            if self.worst < abs(yaw - bad_yaw):
                self.worst = abs(yaw - bad_yaw)
                print "worst: ", self.worst, self.worst * 180 / 3.14159

            if 0.01 < yaw - bad_yaw or yaw - bad_yaw < -0.01:
                print "Aieeeee! bad yaw!", yaw, bad_yaw, yaw - bad_yaw
                exit
            # print "Yaw: %9f" % bad_yaw, "%9.6f" % psi, "%9.6f" % phi,  \
            #      "%9.6f" % twist, "%10.7f" % yaw, "delta %10.7f" % (yaw-bad_yaw)
            # print "Yaw and approximation error", yaw, yaw-bad_yaw
            return yaw

        funcs = {
            'upleft': lambda q: get_upper_left(q),
            'upright': lambda q: get_upper_right(q),
            'yaw': lambda q: get_yaw(q)
        }
        self.map = funcs[args['axis'].lower()]
  def __init__(self, args, motor_entry):

    self.hijoint = NeckKinematics.upper_neck()
    self.lojoint = NeckKinematics.lower_neck()

    # XXX TODO remove hard-coded physical dimensions
    # Han neck mechanism has the upper joint being 8.93 centimeters
    # in front of the lower joint, and 112.16 centimeters above it.
    self.kappa = math.atan2(8.93, 112.16)

    # Returns the upper-neck left motor position, in radians
    def get_upper_left(q) :
        (phi, theta, psi) = quat_to_asa(q)
        try:
            self.hijoint.inverse_kinematics(theta, phi)
        except OverflowError:
            print "Upper left motor jam", theta, phi
        # print "Upper motors:", self.hijoint.theta_l, self.hijoint.theta_r
        return self.hijoint.theta_l

    # Returns the upper-neck right motor position, in radians
    def get_upper_right(q) :
        (phi, theta, psi) = quat_to_asa(q)
        try:
            self.hijoint.inverse_kinematics(theta, phi)
        except OverflowError:
            print "Upper right motor jam", theta, phi
        return self.hijoint.theta_r

    # Returns the lower-neck left motor position, in radians
    def get_lower_left(q) :
        (phi, theta, psi) = quat_to_asa(q)
        # (phi, theta, eta) = NeckVertical.neck_cant(phi, theta, psi, self.kappa)
        try:
            self.lojoint.inverse_kinematics(theta, phi)
        except OverflowError:
            print "Lower left motor jam", theta, phi
        # print "Lower motors:", self.lojoint.theta_l, self.lojoint.theta_r
        return self.lojoint.theta_l

    # Returns the lower-neck right motor position, in radians
    def get_lower_right(q) :
        (phi, theta, psi) = quat_to_asa(q)
        # (phi, theta, eta) = NeckVertical.neck_cant(phi, theta, psi, self.kappa)
        # print "Lower theta-phi:", theta, phi
        try:
            self.lojoint.inverse_kinematics(theta, phi)
        except OverflowError:
            print "Lower right motor jam", theta, phi
        return self.lojoint.theta_r

    # Yaw (spin about neck-skull) axis, in radians, right hand rule.
    def get_yaw(q) :
        (phi, theta, psi) = quat_to_asa(q)

        # XXX TODO The neck cant produces a small correction to the yaw,
        # the formulas are there in neck_cant, but need to be integrated
        # here...

        # The byaw is a "crude" approximation to the correct yaw ...
        # but in fact, the worst-case error is about half a percent,
        # and usually much much better (less than 1/20th of a percent)
        byaw = psi + phi
        if 3.1415926 < byaw:
            byaw -= 2 * 3.14159265358979

        return byaw

    funcs = {
      'upleft':  lambda q: get_upper_left(q),
      'upright': lambda q: get_upper_right(q),
      'loleft':  lambda q: get_lower_left(q),
      'loright': lambda q: get_lower_right(q),
      'yaw': lambda q: get_yaw(q)
    }
    self.map = funcs[args['axis'].lower()]
  def __init__(self, args, motor_entry):

    self.hijoint = NeckKinematics.upper_neck()
    self.lojoint = NeckKinematics.lower_neck()

    # split the angles in two, giving sume to the upper and some to the
    # lower ujoint. Valid values for split are -1.0 to 2.0, with a
    # 50%-50% given by setting split to 0.5.
    # Setting upper_split to 1.0 should result in exactly the same
    # behavior as the Quaternion2Upper class above.
    self.upper_split = 0.5
    self.lower_split = 1.0 - self.upper_split

    # XXX TODO remove hard-coded physical dimensions
    # Han neck mechanism has the upper joint being 8.93 centimeters
    # in front of the lower joint, and 112.16 centimeters above it.
    self.kappa = math.atan2(8.93, 112.16)

    # Returns the upper-neck left motor position, in radians
    def get_upper_left(q) :
        fq = quat_fraction(q, self.upper_split)
        (phi, theta, psi) = quat_to_asa(fq)
        self.hijoint.inverse_kinematics(theta, phi)
        # print "Upper theta-phi:", theta, phi
        # print "Upper motors:", self.hijoint.theta_l, self.hijoint.theta_r
        return self.hijoint.theta_l

    # Returns the upper-neck right motor position, in radians
    def get_upper_right(q) :
        fq = quat_fraction(q, self.upper_split)
        (phi, theta, psi) = quat_to_asa(fq)
        self.hijoint.inverse_kinematics(theta, phi)
        return self.hijoint.theta_r

    # Returns the lower-neck left motor position, in radians
    def get_lower_left(q) :
        fq = quat_fraction(q, self.lower_split)
        (phi, theta, psi) = quat_to_asa(fq)
        # (phi, theta, eta) = NeckVertical.neck_cant(phi, theta, psi, self.kappa)
        self.lojoint.inverse_kinematics(theta, phi)
        # print "Lower theta-phi:", theta, phi
        # print "Lower motors:", self.lojoint.theta_l, self.lojoint.theta_r
        return self.lojoint.theta_l

    # Returns the lower-neck right motor position, in radians
    def get_lower_right(q) :
        fq = quat_fraction(q, self.lower_split)
        (phi, theta, psi) = quat_to_asa(fq)
        # (phi, theta, eta) = NeckVertical.neck_cant(phi, theta, psi, self.kappa)
        self.lojoint.inverse_kinematics(theta, phi)
        return self.lojoint.theta_r

    # Yaw (spin about neck-skull) axis, in radians, right hand rule.
    def get_yaw(q) :
        (phi, theta, psi) = quat_to_asa(q)

        # XXX TODO The neck cant produces a small correction to the yaw,
        # the formulas are there in neck_cant, but need to be integrated
        # here...

        # The byaw is a "crude" approximation to the correct yaw ...
        # but in fact, the worst-case error is about half a percent,
        # and usually much much better (less than 1/20th of a percent)
        byaw = psi + phi
        if 3.1415926 < byaw:
            byaw -= 2 * 3.14159265358979

        return byaw

    funcs = {
      'upleft':  lambda q: get_upper_left(q),
      'upright': lambda q: get_upper_right(q),
      'loleft':  lambda q: get_lower_left(q),
      'loright': lambda q: get_lower_right(q),
      'yaw': lambda q: get_yaw(q)
    }
    self.map = funcs[args['axis'].lower()]
  def __init__(self, args, motor_entry):

    self.hijoint = NeckKinematics.upper_neck()
    self.worst = 0

    # Returns the upper-neck left motor position, in radians
    def get_upper_left(q) :
        (phi, theta, psi) = quat_to_asa(q)
        self.hijoint.inverse_kinematics(theta, phi)
        # print "Motors: left right", self.hijoint.theta_l, self.hijoint.theta_r
        return self.hijoint.theta_l

    # Returns the upper-neck right motor position, in radians
    def get_upper_right(q) :
        (phi, theta, psi) = quat_to_asa(q)
        self.hijoint.inverse_kinematics(theta, phi)
        return self.hijoint.theta_r

    # Yaw (spin about neck-skull) axis, in radians, right hand rule.
    def get_yaw(q) :
        (phi, theta, psi) = quat_to_asa(q)

        # The twist factor is the actual correction for the fact
        # that the gimbal in the neck assembly prevents the u-joint
        # from rotating.
        twist = math.atan2 (math.tan(phi), math.cos(theta))
        if twist < 0 :
            twist += 3.14159265358979

        # The actual neck yaw.
        yaw = psi + twist
        if 3.1415926 < yaw:
            yaw -= 2 * 3.14159265358979

        # The bad_yaw is a "crude" approximation to the correct yaw ...
        # but in fact, the worst-case error is about half a percent,
        # and usually much much better (less than 1/20th of a percent)
        bad_yaw = psi + phi
        if 3.1415926 < bad_yaw:
            bad_yaw -= 2 * 3.14159265358979

        # Hacky corrections to bad quadrant of the arctan...
        if 2 < yaw-bad_yaw :
            yaw -= 3.14159265358979
        if yaw-bad_yaw < -2:
            yaw += 3.14159265358979

        if self.worst < abs(yaw-bad_yaw) :
            self.worst = abs(yaw-bad_yaw)
            print "worst: ", self.worst, self.worst * 180 / 3.14159

        if 0.01 < yaw-bad_yaw or yaw-bad_yaw < -0.01:
            print "Aieeeee! bad yaw!", yaw, bad_yaw, yaw-bad_yaw
            exit
        # print "Yaw: %9f" % bad_yaw, "%9.6f" % psi, "%9.6f" % phi,  \
        #      "%9.6f" % twist, "%10.7f" % yaw, "delta %10.7f" % (yaw-bad_yaw)
        # print "Yaw and approximation error", yaw, yaw-bad_yaw
        return yaw

    funcs = {
      'upleft': lambda q: get_upper_left(q),
      'upright': lambda q: get_upper_right(q),
      'yaw': lambda q: get_yaw(q)
    }
    self.map = funcs[args['axis'].lower()]