示例#1
0
    def calculate_lqr(self):
        upright_plant = AcrobotPlant()
        upright_plant_context = upright_plant.CreateDefaultContext()
        upright_plant_context.get_mutable_continuous_state() \
            .SetFromVector(np.array([np.pi, 0, 0, 0]))
        upright_plant.GetInputPort("elbow_torque") \
            .FixValue(upright_plant_context, 0)

        lqr = LinearQuadraticRegulator(upright_plant, upright_plant_context,
                                       self.Q, self.R)
        return lqr.D()
def make_real_dircol_mp():
    global tree
    global plant
    global context
    global dircol
    # expmt = "acrobot" # State: (theta1, theta2, theta1_dot, theta2_dot) Input: Elbow torque

    tree = RigidBodyTree("/opt/underactuated/src/acrobot/acrobot.urdf",
                     FloatingBaseType.kFixed)
    plant = AcrobotPlant()
    context = plant.CreateDefaultContext()
    dircol = DirectCollocation(plant, context, num_time_samples=21,
                           minimum_timestep=0.05, maximum_timestep=0.2)

    dircol.AddEqualTimeIntervalsConstraints()

    # Add input limits.
    torque_limit = 8.0  # N*m.
    u = dircol.input()
    dircol.AddConstraintToAllKnotPoints(-torque_limit <= u[0])
    dircol.AddConstraintToAllKnotPoints(u[0] <= torque_limit)

    initial_state = (0., 0., 0., 0.)
    dircol.AddBoundingBoxConstraint(initial_state, initial_state,
                                    dircol.initial_state())
    final_state = (math.pi, 0., 0., 0.)
    dircol.AddBoundingBoxConstraint(final_state, final_state,
                                    dircol.final_state())

    R = 10  # Cost on input "effort".
    u = dircol.input()
    dircol.AddRunningCost(R*u[0]**2)

    # Add a final cost equal to the total duration.
    dircol.AddFinalCost(dircol.time())

    initial_x_trajectory = \
        PiecewisePolynomial.FirstOrderHold([0., 4.],
                                           np.column_stack((initial_state,
                                                            final_state)))
    dircol.SetInitialTrajectory(PiecewisePolynomial(), initial_x_trajectory)

    print(id(dircol))
    return dircol
示例#3
0
def BalancingLQR():
    # Design an LQR controller for stabilizing the Acrobot around the upright.
    # Returns a (static) AffineSystem that implements the controller (in
    # the original AcrobotState coordinates).

    acrobot = AcrobotPlant()
    context = acrobot.CreateDefaultContext()

    input = AcrobotInput()
    input.set_tau(0.)
    context.FixInputPort(0, input)

    context.get_mutable_continuous_state_vector()\
        .SetFromVector(UprightState().CopyToVector())

    Q = np.diag((10., 10., 1., 1.))
    R = [1]

    return LinearQuadraticRegulator(acrobot, context, Q, R)
示例#4
0
import math
import numpy as np
import matplotlib.pyplot as plt

from pydrake.all import (DirectCollocation, FloatingBaseType,
                         PiecewisePolynomial, RigidBodyTree, RigidBodyPlant,
                         Solve)
from pydrake.examples.acrobot import AcrobotPlant
from underactuated import (FindResource, PlanarRigidBodyVisualizer)

plant = AcrobotPlant()
context = plant.CreateDefaultContext()

dircol = DirectCollocation(plant,
                           context,
                           num_time_samples=21,
                           minimum_timestep=0.05,
                           maximum_timestep=0.2)

dircol.AddEqualTimeIntervalsConstraints()

# Add input limits.
torque_limit = 8.0  # N*m.
u = dircol.input()
dircol.AddConstraintToAllKnotPoints(-torque_limit <= u[0])
dircol.AddConstraintToAllKnotPoints(u[0] <= torque_limit)

initial_state = (0., 0., 0., 0.)
dircol.AddBoundingBoxConstraint(initial_state, initial_state,
                                dircol.initial_state())
# More elegant version is blocked on drake #8315:
示例#5
0
class EnergyShapingControl(LeafSystem):
    def __init__(self, k1, k2, k3, lqr_angle_range=1.0):
        super().__init__()
        self.k1 = k1
        self.k2 = k2
        self.k3 = k3
        self.acrobot_plant = AcrobotPlant()
        self.acrobot_context = self.acrobot_plant.CreateDefaultContext()
        self.upright_context = self.acrobot_plant.CreateDefaultContext()
        self.upright_context.get_mutable_continuous_state()\
            .SetFromVector(np.array([np.pi, 0, 0, 0]))
        self.lqr_angle_range = lqr_angle_range

        self.DeclareInputPort('estimated state', PortDataType.kVectorValued, 4)
        self.DeclareVectorOutputPort('control', BasicVector(1),
                                     self.calculate_control)
        self.Q = np.diag((10., 10., 1., 1.))
        self.R = [10]
        self.K = self.calculate_lqr()
        self.LQR_on = False

    def calculate_lqr(self):
        upright_plant = AcrobotPlant()
        upright_plant_context = upright_plant.CreateDefaultContext()
        upright_plant_context.get_mutable_continuous_state() \
            .SetFromVector(np.array([np.pi, 0, 0, 0]))
        upright_plant.GetInputPort("elbow_torque") \
            .FixValue(upright_plant_context, 0)

        lqr = LinearQuadraticRegulator(upright_plant, upright_plant_context,
                                       self.Q, self.R)
        return lqr.D()

    def calculate_control(self, context, control_vec):
        input = self.get_input_port(0).Eval(context)
        theta1 = input[0]
        theta2 = input[1]
        theta1_dot = input[2]
        theta2_dot = input[3]

        # Current acrobot context based on input.
        self.acrobot_context \
            .get_mutable_continuous_state() \
            .SetFromVector(input)

        desired_state = np.array([np.pi, 0, 0, 0])
        cost = (desired_state - input).T @ self.Q @ (desired_state - input)
        should_use_lqr = cost < 1

        if not self.LQR_on:
            self.LQR_on = should_use_lqr
            if should_use_lqr:
                print("LQR on {0}".format(context.get_time()))

        if self.LQR_on:
            u = -self.K @ (desired_state - input)
            control_vec.SetFromVector(u)
        else:
            # Bias term of the dynamics.
            bias = self.acrobot_plant.DynamicsBiasTerm(self.acrobot_context)

            # Mass matrix
            M = self.acrobot_plant.MassMatrix(self.acrobot_context)
            m11 = M[0, 0]
            m12 = M[0, 1]
            m21 = M[1, 0]
            m22 = M[1, 1]
            m22_bar = m22 - m21 * m12 / m11
            bias_bar = bias[1] - m21 / m11 * bias[0]

            # Desired energy, upright configuration.
            Ed = self.acrobot_plant.EvalPotentialEnergy(self.upright_context) \
                 + self.acrobot_plant.EvalKineticEnergy(self.upright_context)
            # Current energy.
            Ec = self.acrobot_plant.EvalPotentialEnergy(self.acrobot_context) \
                 + self.acrobot_plant.EvalKineticEnergy(self.acrobot_context)
            E_error = Ec - Ed

            u_bar = E_error * theta1_dot

            u = -self.k1 * theta2 - self.k2 * theta2_dot + self.k3 * u_bar
            tau = m22_bar * u + bias_bar

            control_vec.SetFromVector(np.array([tau]))