Example #1
0
    def test_simulation(self):
        # Basic constant-torque acrobot simulation.
        acrobot = AcrobotPlant()

        # Create the simulator.
        simulator = Simulator(acrobot)
        context = simulator.get_mutable_context()

        # Set an input torque.
        input = AcrobotInput()
        input.set_tau(1.)
        acrobot.GetInputPort("elbow_torque").FixValue(context, input)

        # Set the initial state.
        state = context.get_mutable_continuous_state_vector()
        state.set_theta1(1.)
        state.set_theta1dot(0.)
        state.set_theta2(0.)
        state.set_theta2dot(0.)

        self.assertTrue(acrobot.DynamicsBiasTerm(context).shape == (2, ))
        self.assertTrue(acrobot.MassMatrix(context).shape == (2, 2))
        initial_total_energy = acrobot.EvalPotentialEnergy(context) + \
            acrobot.EvalKineticEnergy(context)

        # Simulate (and make sure the state actually changes).
        initial_state = state.CopyToVector()
        simulator.AdvanceTo(1.0)

        self.assertLessEqual(
            acrobot.EvalPotentialEnergy(context) +
            acrobot.EvalKineticEnergy(context), initial_total_energy)
Example #2
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()
Example #3
0
def simulate(*, initial_state, controller_params, t_final, tape_period):
    """Simulates an Acrobot + Spong controller from the given initial state and
    parameters until the given final time.  Returns the state sampled at the
    given tape_period.
    """
    builder = DiagramBuilder()
    plant = builder.AddSystem(AcrobotPlant())
    controller = builder.AddSystem(AcrobotSpongController())

    builder.Connect(plant.get_output_port(0), controller.get_input_port(0))
    builder.Connect(controller.get_output_port(0), plant.get_input_port(0))
    state_logger = LogOutput(plant.get_output_port(0), builder)
    state_logger.set_publish_period(tape_period)

    diagram = builder.Build()
    simulator = Simulator(diagram)
    context = simulator.get_mutable_context()
    plant_context = diagram.GetMutableSubsystemContext(plant, context)
    controller_context = diagram.GetMutableSubsystemContext(
        controller, context)

    plant_context.SetContinuousState(initial_state)
    controller_context.get_mutable_numeric_parameter(0).SetFromVector(
        controller_params)

    simulator.AdvanceTo(t_final)

    x_tape = state_logger.data()
    return x_tape
Example #4
0
 def test_geometry_with_params(self):
     builder = DiagramBuilder()
     plant = builder.AddSystem(AcrobotPlant())
     scene_graph = builder.AddSystem(SceneGraph())
     geom = AcrobotGeometry.AddToBuilder(
         builder=builder, acrobot_state_port=plant.get_output_port(0),
         acrobot_params=AcrobotParams(), scene_graph=scene_graph)
     builder.Build()
     self.assertIsInstance(geom, AcrobotGeometry)
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
Example #6
0
    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
Example #7
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)
def simulate_acrobot():
    builder = DiagramBuilder()

    acrobot = builder.AddSystem(AcrobotPlant())
    saturation = builder.AddSystem(Saturation(min_value=[-10], max_value=[10]))
    builder.Connect(saturation.get_output_port(0), acrobot.get_input_port(0))
    wrapangles = WrapToSystem(4)
    wrapangles.set_interval(0, 0, 2. * math.pi)
    wrapangles.set_interval(1, -math.pi, math.pi)
    wrapto = builder.AddSystem(wrapangles)
    builder.Connect(acrobot.get_output_port(0), wrapto.get_input_port(0))
    controller = builder.AddSystem(BalancingLQR())
    builder.Connect(wrapto.get_output_port(0), controller.get_input_port(0))
    builder.Connect(controller.get_output_port(0),
                    saturation.get_input_port(0))

    tree = RigidBodyTree(FindResource("acrobot/acrobot.urdf"),
                         FloatingBaseType.kFixed)
    visualizer = builder.AddSystem(
        PlanarRigidBodyVisualizer(tree, xlim=[-4., 4.], ylim=[-4., 4.]))
    builder.Connect(acrobot.get_output_port(0), visualizer.get_input_port(0))

    diagram = builder.Build()
    simulator = Simulator(diagram)
    simulator.set_target_realtime_rate(1.0)
    simulator.set_publish_every_time_step(False)
    context = simulator.get_mutable_context()

    state = context.get_mutable_continuous_state_vector()

    parser = argparse.ArgumentParser()
    parser.add_argument("-N",
                        "--trials",
                        type=int,
                        help="Number of trials to run.",
                        default=5)
    parser.add_argument("-T",
                        "--duration",
                        type=float,
                        help="Duration to run each sim.",
                        default=4.0)
    args = parser.parse_args()

    print(AcrobotPlant)

    for i in range(args.trials):
        context.set_time(0.)
        state.SetFromVector(UprightState().CopyToVector() +
                            0.05 * np.random.randn(4, ))
        simulator.StepTo(args.duration)
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:
Example #10
0
from pydrake.all import (DiagramBuilder, PlanarSceneGraphVisualizer, Simulator,
                         SceneGraph, VectorSystem)
from pydrake.examples.acrobot import (AcrobotGeometry, AcrobotInput,
                                      AcrobotPlant, AcrobotState)
from underactuated import SliderSystem

parser = argparse.ArgumentParser()
parser.add_argument("-T",
                    "--duration",
                    type=float,
                    help="Duration to run sim.",
                    default=10000.0)
args = parser.parse_args()

builder = DiagramBuilder()
acrobot = builder.AddSystem(AcrobotPlant())

scene_graph = builder.AddSystem(SceneGraph())
AcrobotGeometry.AddToBuilder(builder, acrobot.get_output_port(0), scene_graph)
visualizer = builder.AddSystem(
    PlanarSceneGraphVisualizer(scene_graph, xlim=[-4., 4.], ylim=[-4., 4.]))
builder.Connect(scene_graph.get_pose_bundle_output_port(),
                visualizer.get_input_port(0))

ax = visualizer.fig.add_axes([.2, .95, .6, .025])
torque_system = builder.AddSystem(SliderSystem(ax, "Torque", -5., 5.))
builder.Connect(torque_system.get_output_port(0), acrobot.get_input_port(0))

diagram = builder.Build()
simulator = Simulator(diagram)
simulator.set_target_realtime_rate(1.0)
Example #11
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]))
Example #12
0
# import torch
import tensorflow
from pydrake.examples.acrobot import AcrobotPlant

import sys

print(sys.executable)


acrobot = AcrobotPlant()
def make_real_dircol_mp(expmt="cartpole", seed=1776):
    global tree
    global plant
    global context
    global dircol
    # TODO: use the seed in some meaningful way:
    # https://github.com/RobotLocomotion/drake/blob/master/systems/stochastic_systems.h

    assert expmt in ("cartpole", "acrobot")
    # expmt = "cartpole" # State: (x, theta, x_dot, theta_dot) Input: x force
    # expmt = "acrobot" # State: (theta1, theta2, theta1_dot, theta2_dot) Input: Elbow torque

    if expmt == "cartpole":
        tree = RigidBodyTree("/opt/underactuated/src/cartpole/cartpole.urdf",
                             FloatingBaseType.kFixed)
        plant = RigidBodyPlant(tree)
    else:
        tree = RigidBodyTree("/opt/underactuated/src/acrobot/acrobot.urdf",
                             FloatingBaseType.kFixed)
        plant = AcrobotPlant()

    context = plant.CreateDefaultContext()

    if expmt == "cartpole":
        dircol = DirectCollocation(plant,
                                   context,
                                   num_time_samples=21,
                                   minimum_timestep=0.1,
                                   maximum_timestep=0.4)
    else:
        dircol = DirectCollocation(plant,
                                   context,
                                   num_time_samples=21,
                                   minimum_timestep=0.05,
                                   maximum_timestep=0.2)

    dircol.AddEqualTimeIntervalsConstraints()

    if expmt == "acrobot":
        # 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:
    # dircol.AddLinearConstraint(dircol.initial_state() == initial_state)

    if expmt == "cartpole":
        final_state = (0., math.pi, 0., 0.)
    else:
        final_state = (math.pi, 0., 0., 0.)
    dircol.AddBoundingBoxConstraint(final_state, final_state,
                                    dircol.final_state())
    # dircol.AddLinearConstraint(dircol.final_state() == 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)

    return dircol, tree