|
|
@@ -0,0 +1,249 @@
|
|
|
+from CBDMultipleOutput.Source.CBD import ConstantBlock, NegatorBlock, \
|
|
|
+ IntegratorBlock, CBD, ProductBlock, AdderBlock, InverterBlock, DecisionBlock, \
|
|
|
+ GenericBlock, AbsBlock
|
|
|
+from fsa_cbd_woven_classes import InputConstantBlock, CBDState, WhenCrossesZeroTrigger
|
|
|
+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"))
|
|
|
+ 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("End", final=True)
|
|
|
+
|
|
|
+ start = Transition("start", Started, Neutral)
|
|
|
+
|
|
|
+ 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(10.0)); # s
|
|
|
+
|
|
|
+ self.states = [
|
|
|
+ Started,
|
|
|
+ Neutral,
|
|
|
+ Pass_Up,
|
|
|
+ Driver_Up,
|
|
|
+ Pass_Down,
|
|
|
+ Driver_Down,
|
|
|
+ Obj_Detected,
|
|
|
+ End
|
|
|
+ ]
|
|
|
+
|
|
|
+ self.initialState = Started
|
|
|
+
|
|
|
+ self.transitions = [
|
|
|
+ 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=0.0))
|
|
|
+
|
|
|
+ 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 PowerWindowUp(CBD):
|
|
|
+ def __init__(self, blockName, delta_t = 0.01):
|
|
|
+ CBD.__init__(self,blockName, input_ports=[], output_ports=["out_w0","out_v0", "out_Fo100","out_Fo","out_total_force","out_friction_force"])
|
|
|
+
|
|
|
+ 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.addBlock(InputConstantBlock("in_w0", value=0.0))
|
|
|
+ self.addBlock(InputConstantBlock("in_v0", value=0.0))
|
|
|
+
|
|
|
+ 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")
|
|
|
+ self.addConnection("plant", "out_Fo", output_port_name="force_out")
|
|
|
+ self.addConnection("plant", "out_total_force", output_port_name="total_force_out")
|
|
|
+ self.addConnection("plant", "out_friction_force", output_port_name="friction_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","total_force_out","friction_force_out"])
|
|
|
+
|
|
|
+ # See power_window_object.pdf
|
|
|
+
|
|
|
+ self.addBlock(ConstantBlock("m", value=10.0))
|
|
|
+ self.addBlock(ConstantBlock("cw",value=-10.0))
|
|
|
+ self.addBlock(ConstantBlock("zero",value=0.0))
|
|
|
+ self.addBlock(ConstantBlock("k0",value=1000.0))
|
|
|
+ self.addBlock(ConstantBlock("c0",value=-1000.0))
|
|
|
+
|
|
|
+ self.addBlock(InverterBlock("invert_mass"))
|
|
|
+
|
|
|
+ self.addBlock(NegatorBlock("position_object_neg"))
|
|
|
+
|
|
|
+ self.addBlock(ProductBlock("cw_p"))
|
|
|
+ self.addBlock(ProductBlock("divide_m"))
|
|
|
+ self.addBlock(ProductBlock("c0_p"))
|
|
|
+ self.addBlock(ProductBlock("k0_p"))
|
|
|
+ self.addBlock(ProductBlock("object_detect_enable"))
|
|
|
+
|
|
|
+ self.addBlock(AdderBlock("torque_friction"))
|
|
|
+ self.addBlock(AdderBlock("total_forces"))
|
|
|
+ self.addBlock(AdderBlock("object_compare"))
|
|
|
+ self.addBlock(AdderBlock("object_compression"))
|
|
|
+ self.addBlock(AdderBlock("object_displacement"))
|
|
|
+
|
|
|
+ self.addBlock(IntegratorBlock("velocity"))
|
|
|
+ self.addBlock(IntegratorBlock("position"))
|
|
|
+
|
|
|
+ self.addBlock(DecisionBlock("obj_detected"))
|
|
|
+
|
|
|
+ self.addBlock(AbsBlock("abs"))
|
|
|
+
|
|
|
+ self.addConnection("object_detect", "object_detect_enable")
|
|
|
+ self.addConnection("object_position", "position_object_neg")
|
|
|
+ self.addConnection("motor", "torque_friction")
|
|
|
+ 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", "invert_mass")
|
|
|
+ self.addConnection("zero", "obj_detected", input_port_name="F")
|
|
|
+
|
|
|
+ self.addConnection("invert_mass", "divide_m")
|
|
|
+
|
|
|
+ self.addConnection("cw", "cw_p")
|
|
|
+ self.addConnection("k0", "k0_p")
|
|
|
+ self.addConnection("c0", "c0_p")
|
|
|
+ self.addConnection("position_object_neg", "object_compare")
|
|
|
+ self.addConnection("position_object_neg", "object_displacement")
|
|
|
+
|
|
|
+ self.addConnection("cw_p", "torque_friction")
|
|
|
+ self.addConnection("divide_m", "velocity")
|
|
|
+ self.addConnection("c0_p", "object_compression")
|
|
|
+ self.addConnection("k0_p", "object_compression")
|
|
|
+ self.addConnection("object_detect_enable", "total_forces")
|
|
|
+ self.addConnection("object_detect_enable", "abs")
|
|
|
+
|
|
|
+ self.addConnection("abs", "force_out")
|
|
|
+
|
|
|
+ self.addConnection("torque_friction", "total_forces")
|
|
|
+ self.addConnection("torque_friction", "friction_force_out")
|
|
|
+ self.addConnection("total_forces", "divide_m")
|
|
|
+ self.addConnection("total_forces", "total_force_out")
|
|
|
+ self.addConnection("object_compare", "obj_detected", input_port_name="C")
|
|
|
+ self.addConnection("object_compression", "obj_detected", input_port_name="T")
|
|
|
+ self.addConnection("object_displacement", "k0_p")
|
|
|
+
|
|
|
+ self.addConnection("velocity", "position")
|
|
|
+ self.addConnection("velocity", "cw_p")
|
|
|
+ self.addConnection("velocity", "c0_p")
|
|
|
+ self.addConnection("velocity", "velocity_out")
|
|
|
+ self.addConnection("position", "object_displacement")
|
|
|
+ self.addConnection("position", "position_out")
|
|
|
+ self.addConnection("position", "object_compare")
|
|
|
+
|
|
|
+ self.addConnection("obj_detected", "object_detect_enable")
|
|
|
+
|