|
|
@@ -1,127 +1,250 @@
|
|
|
from CBDMultipleOutput.Source.CBD import ConstantBlock, NegatorBlock, \
|
|
|
- IntegratorBlock, CBD, ProductBlock, AdderBlock
|
|
|
+ IntegratorBlock, CBD, ProductBlock, AdderBlock, InverterBlock, DecisionBlock
|
|
|
from fsa_cbd_woven_classes import InputConstantBlock, CBDState, WhenCrossesZeroTrigger
|
|
|
-from fsaclasses import FSAModel, Transition, Event, State
|
|
|
+from fsaclasses import FSAModel, Transition, Event, State, After, Float
|
|
|
|
|
|
|
|
|
class PowerWindow(FSAModel):
|
|
|
def __init__(self):
|
|
|
Started = CBDState("Started", PowerWindowStarted("Started"))
|
|
|
Neutral = State("Neutral")
|
|
|
- Pass_up = CBDState("Pass_up", PowerWindowUp("Pass_up"))
|
|
|
+ Pass_Up = CBDState("Pass_up", PowerWindowUp("Pass_up"))
|
|
|
Driver_Up = CBDState("Driver_Up", PowerWindowUp("Driver_Up"))
|
|
|
Pass_Down = CBDState("Pass_Down", PowerWindowDown("Pass_Down"))
|
|
|
Driver_Down = CBDState("Driver_Down", PowerWindowDown("Driver_Down"))
|
|
|
Obj_Detected = CBDState("Obj_Detected", PowerWindowDown("Obj_Detected"))
|
|
|
+ End = State("Obj_Detected", final=True)
|
|
|
|
|
|
start = Transition("start", Started, Neutral)
|
|
|
|
|
|
- p_up = Transition("p_up", Neutral, Pass_Up)
|
|
|
- p_down = Transition("p_down", Neutral, Pass_Down)
|
|
|
- d_up = Transition("d_up", Neutral, Driver_Up)
|
|
|
- d_down = Transition("d_down", Neutral, Driver_Down)
|
|
|
-
|
|
|
-
|
|
|
- initial2Freefall = Transition("Initial2Freefall", initial, freeFall)
|
|
|
- freefall2Collision = Transition("Freefall2Collision", freeFall, collision)
|
|
|
- freefall2Collision.trigger = WhenCrossesZeroTrigger("x", up_direction=False);
|
|
|
- collision2Freefall = Transition("Collision2Freefall", collision, freeFall)
|
|
|
- freefall2Kicked = Transition("Freefall2Kicked", freeFall, kicked)
|
|
|
- freefall2Kicked.trigger = Event("kick");
|
|
|
- kicked2Freefall = Transition("kicked2Freefall", kicked, freeFall)
|
|
|
- freefall2End = Transition("Freefall2End", freeFall, end)
|
|
|
- freefall2End.trigger = Event("enough");
|
|
|
+ p_up_Neutral = Transition("p_up", Neutral, Pass_Up)
|
|
|
+ p_up_Neutral.trigger = Event("p_up");
|
|
|
+ p_down_Neutral = Transition("p_down", Neutral, Pass_Down)
|
|
|
+ p_down_Neutral.trigger = Event("p_down");
|
|
|
+ d_up_Neutral = Transition("d_up", Neutral, Driver_Up)
|
|
|
+ d_up_Neutral.trigger = Event("d_up");
|
|
|
+ d_down_Neutral = Transition("d_down", Neutral, Driver_Down)
|
|
|
+ d_down_Neutral.trigger = Event("d_down");
|
|
|
+ end_Neutral = Transition("end", Neutral, End)
|
|
|
+ end_Neutral.trigger = Event("end");
|
|
|
+
|
|
|
+
|
|
|
+ stop_Pass_up = Transition("stop", Pass_Up, Neutral)
|
|
|
+ stop_Pass_up.trigger = Event("stop");
|
|
|
+ d_down_Pass_up = Transition("d_down", Pass_Up, Driver_Down)
|
|
|
+ d_down_Pass_up.trigger = Event("d_down");
|
|
|
+ d_up_Pass_up = Transition("d_up", Pass_Up, Driver_Up)
|
|
|
+ d_up_Pass_up.trigger = Event("d_up");
|
|
|
+ when_obj_detected_Pass_up = Transition("when_obj_detected", Pass_Up, Obj_Detected)
|
|
|
+ when_obj_detected_Pass_up.trigger = WhenCrossesZeroTrigger("Fo100", up_direction=True)
|
|
|
+
|
|
|
+ stop_Driver_Up = Transition("stop", Driver_Up, Neutral)
|
|
|
+ stop_Driver_Up.trigger = Event("stop");
|
|
|
+ when_obj_detected_Driver_Up = Transition("when_obj_detected", Driver_Up, Obj_Detected)
|
|
|
+ when_obj_detected_Driver_Up.trigger = WhenCrossesZeroTrigger("Fo100", up_direction=True)
|
|
|
+
|
|
|
+ stop_Pass_Down = Transition("stop", Pass_Down, Neutral)
|
|
|
+ stop_Pass_Down.trigger = Event("stop");
|
|
|
+ d_down_Pass_Down = Transition("d_down", Pass_Down, Driver_Down)
|
|
|
+ d_down_Pass_Down.trigger = Event("d_down");
|
|
|
+ d_up_Pass_Down = Transition("d_up", Pass_Down, Driver_Up)
|
|
|
+ d_up_Pass_Down.trigger = Event("d_up");
|
|
|
+
|
|
|
+ stop_Driver_Down = Transition("stop", Driver_Down, Neutral)
|
|
|
+ stop_Driver_Down.trigger = Event("stop");
|
|
|
+
|
|
|
+ stop_Obj_Detected = Transition("after", Obj_Detected, Neutral)
|
|
|
+ stop_Obj_Detected.trigger = After(Float(1000.0)); # ms
|
|
|
|
|
|
self.states = [
|
|
|
- initial,
|
|
|
- freeFall,
|
|
|
- collision,
|
|
|
- kicked,
|
|
|
- end
|
|
|
+ Started,
|
|
|
+ Neutral,
|
|
|
+ Pass_Up,
|
|
|
+ Driver_Up,
|
|
|
+ Pass_Down,
|
|
|
+ Driver_Down,
|
|
|
+ Obj_Detected,
|
|
|
+ End
|
|
|
]
|
|
|
|
|
|
- self.initialState = initial
|
|
|
+ self.initialState = Started
|
|
|
|
|
|
self.transitions = [
|
|
|
- initial2Freefall,
|
|
|
- freefall2Collision,
|
|
|
- collision2Freefall,
|
|
|
- freefall2Kicked,
|
|
|
- kicked2Freefall,
|
|
|
- freefall2End
|
|
|
+ start,
|
|
|
+ p_up_Neutral,
|
|
|
+ p_down_Neutral,
|
|
|
+ d_up_Neutral,
|
|
|
+ d_down_Neutral,
|
|
|
+ end_Neutral,
|
|
|
+ stop_Pass_up,
|
|
|
+ d_down_Pass_up,
|
|
|
+ d_up_Pass_up,
|
|
|
+ when_obj_detected_Pass_up,
|
|
|
+ stop_Driver_Up,
|
|
|
+ when_obj_detected_Driver_Up,
|
|
|
+ stop_Pass_Down,
|
|
|
+ d_down_Pass_Down,
|
|
|
+ d_up_Pass_Down,
|
|
|
+ stop_Driver_Down,
|
|
|
+ stop_Obj_Detected
|
|
|
]
|
|
|
+
|
|
|
+class PowerWindowStarted(CBD):
|
|
|
+ def __init__(self, blockName, delta_t = 0.01):
|
|
|
+ CBD.__init__(self,blockName, input_ports=[], output_ports=["out_w0","out_v0"])
|
|
|
+
|
|
|
+ self.addBlock(ConstantBlock("0", value=delta_t))
|
|
|
|
|
|
-
|
|
|
-
|
|
|
+ self.addConnection("0", "out_w0")
|
|
|
+ self.addConnection("0", "out_v0")
|
|
|
+
|
|
|
+class PowerWindowDown(CBD):
|
|
|
+ def __init__(self, blockName, delta_t = 0.01):
|
|
|
+ CBD.__init__(self,blockName, input_ports=[], output_ports=["out_w0","out_v0"])
|
|
|
|
|
|
+ self.addBlock(ConstantBlock("delta_t", value=delta_t))
|
|
|
+ self.addBlock(ConstantBlock("torque", value=-2.0))
|
|
|
+ self.addBlock(ConstantBlock("0", value=0.0))
|
|
|
+ self.addBlock(ConstantBlock("100", value=100.0))
|
|
|
|
|
|
+ self.addBlock(InputConstantBlock("in_w0", value=0.0))
|
|
|
+ self.addBlock(InputConstantBlock("in_v0", value=0.0))
|
|
|
+
|
|
|
+ self.addBlock(PowerWindowPlant("plant"))
|
|
|
+
|
|
|
+ self.addConnection("delta_t", "plant", input_port_name="delta_t")
|
|
|
+ self.addConnection("torque", "plant", input_port_name="motor")
|
|
|
+ self.addConnection("0", "plant", input_port_name="object_detect")
|
|
|
+ self.addConnection("100", "plant", input_port_name="object_position")
|
|
|
+
|
|
|
+ self.addConnection("in_w0", "plant", input_port_name="init_position")
|
|
|
+ self.addConnection("in_v0", "plant", input_port_name="init_velocity")
|
|
|
+
|
|
|
+ self.addConnection("plant", "out_w0", output_port_name="position_out")
|
|
|
+ self.addConnection("plant", "out_v0", output_port_name="velocity_out")
|
|
|
|
|
|
-class BouncingBallFreefall(CBD):
|
|
|
+class PowerWindowUp(CBD):
|
|
|
def __init__(self, blockName, delta_t = 0.01):
|
|
|
- CBD.__init__(self,blockName, input_ports=[], output_ports=["out_v", "out_x"])
|
|
|
-
|
|
|
- self.addBlock(InputConstantBlock(block_name="in_x"))
|
|
|
- self.addBlock(InputConstantBlock(block_name="in_v"))
|
|
|
-
|
|
|
- self.addBlock(ConstantBlock(block_name="gravity", value=-9.81))
|
|
|
- self.addBlock(ConstantBlock(block_name="delta", value=delta_t))
|
|
|
-
|
|
|
- self.addBlock(IntegratorBlock(block_name="intgv"))
|
|
|
- self.addBlock(IntegratorBlock(block_name="intvx"))
|
|
|
-
|
|
|
- self.addConnection("delta", "intgv", input_port_name="delta_t")
|
|
|
- self.addConnection("delta", "intvx", input_port_name="delta_t")
|
|
|
- self.addConnection("in_v", "intgv", input_port_name="IC")
|
|
|
- self.addConnection("in_x", "intvx", input_port_name="IC")
|
|
|
-
|
|
|
- self.addConnection("gravity", "intgv")
|
|
|
- self.addConnection("intgv", "intvx")
|
|
|
- self.addConnection("intgv", "out_v")
|
|
|
- self.addConnection("intvx", "out_x")
|
|
|
-
|
|
|
- def setDeltaT(self, deltaT):
|
|
|
- CBD.setDeltaT(self, deltaT)
|
|
|
- self.getBlockByName("delta").setValue(deltaT);
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-class BouncingBallInitial(CBD):
|
|
|
- def __init__(self, blockName, delta_t=0.01):
|
|
|
- CBD.__init__(self,blockName, input_ports=[], output_ports=["out_v", "out_x"])
|
|
|
+ CBD.__init__(self,blockName, input_ports=[], output_ports=["out_w0","out_v0", "out_Fo100"])
|
|
|
|
|
|
- self.addBlock(ConstantBlock(block_name="init_velocity", value=15.0))
|
|
|
- self.addBlock(ConstantBlock(block_name="init_position", value=10.0))
|
|
|
+ self.addBlock(ConstantBlock("delta_t", value=delta_t))
|
|
|
+ self.addBlock(ConstantBlock("torque", value=2.0))
|
|
|
+ self.addBlock(ConstantBlock("1", value=1.0))
|
|
|
+ self.addBlock(ConstantBlock("0.4", value=0.4))
|
|
|
+ self.addBlock(ConstantBlock("force_threshold", value=-100))
|
|
|
|
|
|
- self.addConnection("init_velocity", "out_v")
|
|
|
- self.addConnection("init_position", "out_x")
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-class BouncingBallCollision(CBD):
|
|
|
- def __init__(self, blockName, delta_t=0.01):
|
|
|
- CBD.__init__(self,blockName, input_ports=[], output_ports=["out_v"])
|
|
|
+ self.addBlock(InputConstantBlock("in_w0", value=0.0))
|
|
|
+ self.addBlock(InputConstantBlock("in_v0", value=0.0))
|
|
|
|
|
|
- self.addBlock(InputConstantBlock(block_name="in_v"))
|
|
|
+ self.addBlock(AdderBlock("compare_force"))
|
|
|
+
|
|
|
+ self.addBlock(PowerWindowPlant("plant"))
|
|
|
+
|
|
|
+
|
|
|
+ self.addConnection("delta_t", "plant", input_port_name="delta_t")
|
|
|
+ self.addConnection("torque", "plant", input_port_name="motor")
|
|
|
+ self.addConnection("1", "plant", input_port_name="object_detect")
|
|
|
+ self.addConnection("0.4", "plant", input_port_name="object_position")
|
|
|
+ self.addConnection("force_threshold", "compare_force")
|
|
|
+
|
|
|
+ self.addConnection("in_w0", "plant", input_port_name="init_position")
|
|
|
+ self.addConnection("in_v0", "plant", input_port_name="init_velocity")
|
|
|
+
|
|
|
+ self.addConnection("compare_force", "out_Fo100")
|
|
|
+
|
|
|
+ self.addConnection("plant", "out_w0", output_port_name="position_out")
|
|
|
+ self.addConnection("plant", "out_v0", output_port_name="velocity_out")
|
|
|
+ self.addConnection("plant", "compare_force", output_port_name="force_out")
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+class PowerWindowPlant(CBD):
|
|
|
+ def __init__(self, blockName, delta_t = 0.01):
|
|
|
+ CBD.__init__(self,blockName, input_ports=[
|
|
|
+ "object_detect",
|
|
|
+ "object_position",
|
|
|
+ "motor",
|
|
|
+ "init_position",
|
|
|
+ "init_velocity",
|
|
|
+ "delta_t"
|
|
|
+ ], output_ports=["position_out","velocity_out","force_out"])
|
|
|
+
|
|
|
+ # See power_window_object.pdf
|
|
|
+
|
|
|
+ self.addBlock(ConstantBlock("m", value=10.0))
|
|
|
+ self.addBlock(ConstantBlock("cw",value=10.0))
|
|
|
+ self.addBlock(ConstantBlock("0",value=0.0))
|
|
|
+ self.addBlock(ConstantBlock("k0",value=1000.0))
|
|
|
+ self.addBlock(ConstantBlock("c0",value=1000.0))
|
|
|
+
|
|
|
+ self.addBlock(InverterBlock("1/m"))
|
|
|
+
|
|
|
+ self.addBlock(NegatorBlock("-cw"))
|
|
|
+ self.addBlock(NegatorBlock("-k0"))
|
|
|
+ self.addBlock(NegatorBlock("-c0"))
|
|
|
+ self.addBlock(NegatorBlock("-position"))
|
|
|
+
|
|
|
+ self.addBlock(ProductBlock("-cw_p"))
|
|
|
+ self.addBlock(ProductBlock("1/m_p"))
|
|
|
+ self.addBlock(ProductBlock("-c0_p"))
|
|
|
+ self.addBlock(ProductBlock("-k0_p"))
|
|
|
+ self.addBlock(ProductBlock("object_detect_enable"))
|
|
|
+
|
|
|
+ self.addBlock(AdderBlock("acceleration"))
|
|
|
+ self.addBlock(AdderBlock("objectF+acceleration"))
|
|
|
+ self.addBlock(AdderBlock("object_compare"))
|
|
|
+ self.addBlock(AdderBlock("object_compression"))
|
|
|
+
|
|
|
+ self.addBlock(IntegratorBlock("velocity"))
|
|
|
+ self.addBlock(IntegratorBlock("position"))
|
|
|
+
|
|
|
+ self.addBlock(DecisionBlock("obj_detected"))
|
|
|
+
|
|
|
+
|
|
|
+ self.addConnection("object_detect", "object_detect_enable")
|
|
|
+ self.addConnection("object_position", "object_compare")
|
|
|
+ self.addConnection("motor", "1/m_p")
|
|
|
+ self.addConnection("init_position", "position", input_port_name="IC")
|
|
|
+ self.addConnection("init_velocity", "velocity", input_port_name="IC")
|
|
|
+ self.addConnection("delta_t", "position", input_port_name="delta_t")
|
|
|
+ self.addConnection("delta_t", "velocity", input_port_name="delta_t")
|
|
|
+
|
|
|
+ self.addConnection("m", "1/m")
|
|
|
+ self.addConnection("cw", "-cw")
|
|
|
+ self.addConnection("0", "obj_detected", input_port_name="F")
|
|
|
+ self.addConnection("k0", "-k0")
|
|
|
+ self.addConnection("c0", "-c0")
|
|
|
+
|
|
|
+ self.addConnection("1/m", "1/m_p")
|
|
|
+
|
|
|
+ self.addConnection("-cw", "-cw_p")
|
|
|
+ self.addConnection("-k0", "-k0_p")
|
|
|
+ self.addConnection("-c0", "-c0_p")
|
|
|
+ self.addConnection("-position", "object_compare")
|
|
|
+
|
|
|
+ self.addConnection("-cw_p", "acceleration")
|
|
|
+ self.addConnection("1/m_p", "acceleration")
|
|
|
+ self.addConnection("-c0_p", "object_compression")
|
|
|
+ self.addConnection("-k0_p", "object_compression")
|
|
|
+ self.addConnection("object_detect_enable", "objectF+acceleration")
|
|
|
+ self.addConnection("object_detect_enable", "force_out")
|
|
|
+
|
|
|
+ self.addConnection("acceleration", "objectF+acceleration")
|
|
|
+ self.addConnection("objectF+acceleration", "velocity")
|
|
|
+ self.addConnection("object_compare", "obj_detected", input_port_name="C")
|
|
|
+ self.addConnection("object_compression", "obj_detected", input_port_name="T")
|
|
|
+
|
|
|
+ self.addConnection("velocity", "position")
|
|
|
+ self.addConnection("velocity", "-cw_p")
|
|
|
+ self.addConnection("velocity", "-c0_p")
|
|
|
+ self.addConnection("velocity", "velocity_out")
|
|
|
+ self.addConnection("position", "-k0_p")
|
|
|
+ self.addConnection("position", "position_out")
|
|
|
+ self.addConnection("position", "-position")
|
|
|
+
|
|
|
+ self.addConnection("obj_detected", "object_detect_enable")
|
|
|
|
|
|
- self.addBlock(ConstantBlock(block_name="coeficient", value=-0.8))
|
|
|
- self.addBlock(ProductBlock(block_name="mult"))
|
|
|
|
|
|
- self.addConnection("in_v", "mult")
|
|
|
- self.addConnection("coeficient", "mult")
|
|
|
- self.addConnection("mult", "out_v")
|
|
|
-
|
|
|
-
|
|
|
-class BouncingBallKicked(CBD):
|
|
|
- def __init__(self, blockName, delta_t=0.01):
|
|
|
- CBD.__init__(self,blockName, input_ports=[], output_ports=["out_v"])
|
|
|
|
|
|
- self.addBlock(InputConstantBlock(block_name="in_v"))
|
|
|
|
|
|
- self.addBlock(ConstantBlock(block_name="kick_impact", value=20))
|
|
|
- self.addBlock(AdderBlock(block_name="sum"))
|
|
|
|
|
|
- self.addConnection("in_v", "sum")
|
|
|
- self.addConnection("kick_impact", "sum")
|
|
|
- self.addConnection("sum", "out_v")
|
|
|
-
|
|
|
-
|