PlanarMechanics.examples.excavator.ControlledCylinder
A hydraulic cylinder axis with its own valve, sensors, and cascade controller.
Bundles a ProportionalValve, a double-acting cylinder, position/velocity/force sensors at the cylinder flange, and a CascadeServoController into a single reusable actuator. The supply and tank ports connect to the shared hydraulic network; the mechanical flange drives the load (typically through a PlanarCylinderMount); the position, velocity, and acceleration reference inputs come from a trajectory generator.
Usage
MultibodyComponents.PlanarMechanics.examples.excavator.ControlledCylinder(Kv=5e-7, stroke=0.5, M=10, area_a=3e-3, area_b=2e-3, p_a0=1e6, p_b0=5e5, k_pos=6, v_max=0.5, k_vel=0.625, Ti_vel=1.5, f_max=8e4, ka_ff=0, k_force=0.08, Ti_force=0.02)
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
Kv | Valve flow coefficient | – | 5e-7 |
stroke | Cylinder stroke (piston travel and barrel length) | m | 0.5 |
M | Piston mass | kg | 10 |
area_a | Cap-side piston area | m2 | 3e-3 |
area_b | Rod-side piston area | m2 | 2e-3 |
p_a0 | Initial cap-side chamber pressure | – | 1e6 |
p_b0 | Initial rod-side chamber pressure | – | 5e5 |
k_pos | Position-loop bandwidth (commanded velocity per unit position error) | – | 6 |
v_max | Rated cylinder speed (velocity limit and scale) | – | 0.5 |
k_vel | Dimensionless velocity-loop gain | – | 0.625 |
Ti_vel | Velocity-loop integrator time constant | s | 1.5 |
f_max | Rated cylinder force (force limit and scale) | – | 8e4 |
ka_ff | Acceleration feedforward gain (reflected inertia) | – | 0 |
k_force | Dimensionless force-loop gain | – | 0.08 |
Ti_force | Force-loop integrator time constant | s | 0.02 |
Connectors
port_p- (Port)port_t- (Port)flange- This connector represents a mechanical flange with position and force as the potential and flow variables, respectively. (Flange)s_ref- This connector represents a real signal as an input to a component (RealInput)v_ff- This connector represents a real signal as an input to a component (RealInput)a_ff- This connector represents a real signal as an input to a component (RealInput)
Behavior
Behavior of this component cannot be rendered because it includes path variables.
Source
"""
A hydraulic cylinder axis with its own valve, sensors, and cascade controller.
Bundles a `ProportionalValve`, a double-acting cylinder, position/velocity/force
sensors at the cylinder flange, and a `CascadeServoController` into a single
reusable actuator. The supply and tank ports connect to the shared hydraulic
network; the mechanical `flange` drives the load (typically through a
`PlanarCylinderMount`); the position, velocity, and acceleration reference
inputs come from a trajectory generator.
"""
component ControlledCylinder
"Supply (pump) port"
port_p = HydraulicComponents.Interfaces.Port() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 300, "y1": 950, "x2": 400, "y2": 1050, "rot": 0}
},
"tags": []
}
}
"Tank (return) port"
port_t = HydraulicComponents.Interfaces.Port() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 600, "y1": 950, "x2": 700, "y2": 1050, "rot": 0}
},
"tags": []
}
}
"Mechanical flange driving the load"
flange = Flange() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 950, "y1": 450, "x2": 1050, "y2": 550, "rot": 0}
},
"tags": []
}
}
"Piston position reference"
s_ref = RealInput() {
"Dyad": {"placement": {"diagram": {"x1": -50, "y1": 140, "x2": 50, "y2": 240}}}
}
"Piston velocity reference"
v_ff = RealInput() {
"Dyad": {"placement": {"diagram": {"x1": -50, "y1": 450, "x2": 50, "y2": 550}}}
}
"Piston acceleration reference"
a_ff = RealInput() {
"Dyad": {"placement": {"diagram": {"x1": -50, "y1": 700, "x2": 50, "y2": 800}}}
}
valve = ProportionalValve(Kv = Kv) {
"Dyad": {"placement": {"diagram": {"x1": 480, "y1": 700, "x2": 630, "y2": 900}}}
}
cylinder = HydraulicComponents.Machines.DoubleActingCylinder(L = stroke, M = M, area_a = area_a, area_b = area_b, s0 = missing) {
"Dyad": {"placement": {"diagram": {"x1": 440, "y1": 600, "x2": 640, "y2": 400}}}
}
psens = TranslationalComponents.Sensors.PositionSensor() {
"Dyad": {
"placement": {"diagram": {"x1": 130, "y1": 110, "x2": 210, "y2": 190, "rot": 90}}
}
}
vsens = TranslationalComponents.Sensors.SpeedSensor() {
"Dyad": {
"placement": {"diagram": {"x1": 220, "y1": 110, "x2": 300, "y2": 190, "rot": 90}}
}
}
fsens = TranslationalComponents.Sensors.ForceSensor() {
"Dyad": {
"placement": {"diagram": {"x1": 580, "y1": 190, "x2": 500, "y2": 270, "rot": 90}}
}
}
servo = MultibodyComponents.CascadeServoController(final k_pos = k_pos, final v_max = v_max, final k_vel = k_vel, final Ti_vel = Ti_vel, final f_max = f_max, final ka_ff = ka_ff, final k_force = k_force, final Ti_force = Ti_force) {
"Dyad": {"placement": {"diagram": {"x1": 150, "y1": 450, "x2": 350, "y2": 250}}}
}
"Valve flow coefficient"
parameter Kv::Real = 5e-7
"Cylinder stroke (piston travel and barrel length)"
parameter stroke::Length = 0.5
"Piston mass"
parameter M::Mass = 10
"Cap-side piston area"
parameter area_a::Area = 3e-3
"Rod-side piston area"
parameter area_b::Area = 2e-3
"Initial cap-side chamber pressure"
parameter p_a0::Real = 1e6
"Initial rod-side chamber pressure"
parameter p_b0::Real = 5e5
"Position-loop bandwidth (commanded velocity per unit position error)"
parameter k_pos::Real = 6
"Rated cylinder speed (velocity limit and scale)"
parameter v_max::Real = 0.5
"Dimensionless velocity-loop gain"
parameter k_vel::Real = 0.625
"Velocity-loop integrator time constant"
parameter Ti_vel::Time = 1.5
"Rated cylinder force (force limit and scale)"
parameter f_max::Real = 8e4
"Acceleration feedforward gain (reflected inertia)"
parameter ka_ff::Real = 0
"Dimensionless force-loop gain"
parameter k_force::Real = 0.08
"Force-loop integrator time constant"
parameter Ti_force::Time = 0.02
relations
initial cylinder.port_a.p = p_a0
initial cylinder.port_b.p = p_b0
connect(servo.s_ref, s_ref) {"Dyad": {"edges": [{"S": 1, "M": [{"x": 0, "y": 350}], "E": 2}]}}
connect(v_ff, servo.v_ff) {"Dyad": {"edges": [{"S": 1, "M": [{"x": 206, "y": 500}], "E": 2}]}}
connect(servo.a_ff, a_ff) {"Dyad": {"edges": [{"S": 1, "M": [{"x": 292, "y": 750}], "E": 2}]}}
connect(psens.s, servo.s_meas) {
"Dyad": {"edges": [{"S": 1, "M": [{"x": 170, "y": 201}, {"x": 192, "y": 201}], "E": 2}]}
}
connect(vsens.v, servo.v_meas) {
"Dyad": {"edges": [{"S": 1, "M": [{"x": 260, "y": 221}, {"x": 250, "y": 221}], "E": 2}]}
}
connect(port_t, valve.port_t) {"Dyad": {"edges": [{"S": 1, "M": [{"x": 592.5, "y": 1000}], "E": 2}]}}
connect(valve.port_b, cylinder.port_b) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [{"x": 592.5, "y": 660}, {"x": 670, "y": 660}, {"x": 670, "y": 500}],
"E": 2
}
]
}
}
connect(valve.port_a, cylinder.port_a) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [{"x": 517.5, "y": 660}, {"x": 410, "y": 660}, {"x": 410, "y": 500}],
"E": 2
}
]
}
}
connect(valve.port_p, port_p) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 517.5, "y": 940}, {"x": 350, "y": 940}], "E": 2}]
}
}
connect(fsens.f, servo.f_meas) {"Dyad": {"edges": [{"S": 1, "M": [{"x": 308, "y": 230}], "E": 2}]}}
connect(fsens.flange_b, flange) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [{"x": 540, "y": 150}, {"x": 870, "y": 150}, {"x": 870, "y": 500}],
"E": 2
}
]
}
}
connect(fsens.flange_a, cylinder.flange) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}]}}
metadata {
"Dyad": {"icons": {"default": "dyad://MultibodyComponents/ControlledCylinder.svg"}}
}
endFlattened Source
"""
A hydraulic cylinder axis with its own valve, sensors, and cascade controller.
Bundles a `ProportionalValve`, a double-acting cylinder, position/velocity/force
sensors at the cylinder flange, and a `CascadeServoController` into a single
reusable actuator. The supply and tank ports connect to the shared hydraulic
network; the mechanical `flange` drives the load (typically through a
`PlanarCylinderMount`); the position, velocity, and acceleration reference
inputs come from a trajectory generator.
"""
component ControlledCylinder
"Supply (pump) port"
port_p = HydraulicComponents.Interfaces.Port() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 300, "y1": 950, "x2": 400, "y2": 1050, "rot": 0}
},
"tags": []
}
}
"Tank (return) port"
port_t = HydraulicComponents.Interfaces.Port() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 600, "y1": 950, "x2": 700, "y2": 1050, "rot": 0}
},
"tags": []
}
}
"Mechanical flange driving the load"
flange = Flange() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 950, "y1": 450, "x2": 1050, "y2": 550, "rot": 0}
},
"tags": []
}
}
"Piston position reference"
s_ref = RealInput() {
"Dyad": {"placement": {"diagram": {"x1": -50, "y1": 140, "x2": 50, "y2": 240}}}
}
"Piston velocity reference"
v_ff = RealInput() {
"Dyad": {"placement": {"diagram": {"x1": -50, "y1": 450, "x2": 50, "y2": 550}}}
}
"Piston acceleration reference"
a_ff = RealInput() {
"Dyad": {"placement": {"diagram": {"x1": -50, "y1": 700, "x2": 50, "y2": 800}}}
}
valve = ProportionalValve(Kv = Kv) {
"Dyad": {"placement": {"diagram": {"x1": 480, "y1": 700, "x2": 630, "y2": 900}}}
}
cylinder = HydraulicComponents.Machines.DoubleActingCylinder(L = stroke, M = M, area_a = area_a, area_b = area_b, s0 = missing) {
"Dyad": {"placement": {"diagram": {"x1": 440, "y1": 600, "x2": 640, "y2": 400}}}
}
psens = TranslationalComponents.Sensors.PositionSensor() {
"Dyad": {
"placement": {"diagram": {"x1": 130, "y1": 110, "x2": 210, "y2": 190, "rot": 90}}
}
}
vsens = TranslationalComponents.Sensors.SpeedSensor() {
"Dyad": {
"placement": {"diagram": {"x1": 220, "y1": 110, "x2": 300, "y2": 190, "rot": 90}}
}
}
fsens = TranslationalComponents.Sensors.ForceSensor() {
"Dyad": {
"placement": {"diagram": {"x1": 580, "y1": 190, "x2": 500, "y2": 270, "rot": 90}}
}
}
servo = MultibodyComponents.CascadeServoController(final k_pos = k_pos, final v_max = v_max, final k_vel = k_vel, final Ti_vel = Ti_vel, final f_max = f_max, final ka_ff = ka_ff, final k_force = k_force, final Ti_force = Ti_force) {
"Dyad": {"placement": {"diagram": {"x1": 150, "y1": 450, "x2": 350, "y2": 250}}}
}
"Valve flow coefficient"
parameter Kv::Real = 5e-7
"Cylinder stroke (piston travel and barrel length)"
parameter stroke::Length = 0.5
"Piston mass"
parameter M::Mass = 10
"Cap-side piston area"
parameter area_a::Area = 3e-3
"Rod-side piston area"
parameter area_b::Area = 2e-3
"Initial cap-side chamber pressure"
parameter p_a0::Real = 1e6
"Initial rod-side chamber pressure"
parameter p_b0::Real = 5e5
"Position-loop bandwidth (commanded velocity per unit position error)"
parameter k_pos::Real = 6
"Rated cylinder speed (velocity limit and scale)"
parameter v_max::Real = 0.5
"Dimensionless velocity-loop gain"
parameter k_vel::Real = 0.625
"Velocity-loop integrator time constant"
parameter Ti_vel::Time = 1.5
"Rated cylinder force (force limit and scale)"
parameter f_max::Real = 8e4
"Acceleration feedforward gain (reflected inertia)"
parameter ka_ff::Real = 0
"Dimensionless force-loop gain"
parameter k_force::Real = 0.08
"Force-loop integrator time constant"
parameter Ti_force::Time = 0.02
relations
initial cylinder.port_a.p = p_a0
initial cylinder.port_b.p = p_b0
connect(servo.s_ref, s_ref) {"Dyad": {"edges": [{"S": 1, "M": [{"x": 0, "y": 350}], "E": 2}]}}
connect(v_ff, servo.v_ff) {"Dyad": {"edges": [{"S": 1, "M": [{"x": 206, "y": 500}], "E": 2}]}}
connect(servo.a_ff, a_ff) {"Dyad": {"edges": [{"S": 1, "M": [{"x": 292, "y": 750}], "E": 2}]}}
connect(psens.s, servo.s_meas) {
"Dyad": {"edges": [{"S": 1, "M": [{"x": 170, "y": 201}, {"x": 192, "y": 201}], "E": 2}]}
}
connect(vsens.v, servo.v_meas) {
"Dyad": {"edges": [{"S": 1, "M": [{"x": 260, "y": 221}, {"x": 250, "y": 221}], "E": 2}]}
}
connect(port_t, valve.port_t) {"Dyad": {"edges": [{"S": 1, "M": [{"x": 592.5, "y": 1000}], "E": 2}]}}
connect(valve.port_b, cylinder.port_b) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [{"x": 592.5, "y": 660}, {"x": 670, "y": 660}, {"x": 670, "y": 500}],
"E": 2
}
]
}
}
connect(valve.port_a, cylinder.port_a) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [{"x": 517.5, "y": 660}, {"x": 410, "y": 660}, {"x": 410, "y": 500}],
"E": 2
}
]
}
}
connect(valve.port_p, port_p) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 517.5, "y": 940}, {"x": 350, "y": 940}], "E": 2}]
}
}
connect(fsens.f, servo.f_meas) {"Dyad": {"edges": [{"S": 1, "M": [{"x": 308, "y": 230}], "E": 2}]}}
connect(fsens.flange_b, flange) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [{"x": 540, "y": 150}, {"x": 870, "y": 150}, {"x": 870, "y": 500}],
"E": 2
}
]
}
}
connect(fsens.flange_a, cylinder.flange) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}]}}
metadata {
"Dyad": {"icons": {"default": "dyad://MultibodyComponents/ControlledCylinder.svg"}}
}
endTest Cases
No test cases defined.
Related
Examples
Experiments
Analyses