├── application_control
├── CMakeLists.txt
├── diagnostics
│ └── diagnostics_main.yaml
├── halcon_external_procedures
│ ├── close_active_window.hdvp
│ └── find_area_pepper.hdvp
├── include
│ ├── ColdBootState.h
│ ├── MoveToHomeState.h
│ ├── ReadyState.h
│ ├── ScanPlantState.h
│ ├── SimpleActionState.h
│ ├── State.h
│ ├── StateMachine.h
│ ├── TransitionParser.h
│ └── VisualServoState.h
├── msg
│ ├── State.msg
│ └── changeState.msg
├── package.xml
├── readme.txt
├── servo.launch
├── src
│ ├── ColdBootState.cpp
│ ├── Main.cpp
│ ├── MoveToHomeState.cpp
│ ├── ReadyState.cpp
│ ├── ScanPlantState.cpp
│ └── VisualServoState.cpp
├── srv
│ ├── PauseRequest.srv
│ └── request_camera_parameters.srv
└── transitions
│ ├── transitions.dot
│ └── transitions.yaml
├── fruit_detection
├── CMakeLists.txt
├── halcon_external_procedures
│ └── find_pepper_features.hdvp
├── include
│ ├── fruit_detection_node.h
│ └── window_handling.h
├── package.xml
├── src
│ └── fruit_detection_node.cpp
└── srv
│ └── request_features.srv
├── image_acquisition
├── CMakeLists.txt
├── camera_parameters
│ ├── calculate_camera_parameter_tis_camera.hdev
│ ├── calibration_model_125.descr
│ └── tis_camera_parameters.dat
├── halcon_external_procedures
│ ├── close_frame_grabber.hdvp
│ ├── display_grabbed_image.hdvp
│ ├── grab_image_resized.hdvp
│ ├── grab_rectified_image.hdvp
│ ├── grab_rectified_image_640_480.hdvp
│ ├── grab_rectified_image_640_480_COLORSPACE.hdvp
│ ├── grab_rectified_image_640_480_GRAY.hdvp
│ ├── initialize_camera_tis.hdvp
│ ├── initialize_camera_tis_640_480.hdvp
│ └── read_camera_parameters.hdvp
├── halcon_scripts
│ ├── cake_test.hdev
│ ├── image_analysis.hdev
│ └── image_analysis_2.hdev
├── images
│ └── cake.jpg
├── include
│ ├── image_acquisition_node.h
│ └── window_handling.h
├── package.xml
├── src
│ └── image_acquisition_node.cpp
└── srv
│ ├── request_camera_parameters.srv
│ └── request_image.srv
├── robot_control
├── CMakeLists.txt
├── action
│ └── MoveArm.action
├── package.xml
├── src
│ └── robot_control_action_server.cpp
└── srv
│ └── request_endpointstate.srv
├── slam_bridge
├── CMakeLists.txt
├── calibration_files
│ ├── pre-rectified_images.cfg
│ └── readme.txt
├── include
│ └── lsd_slam_pointcloud_publisher.h
├── msg
│ ├── keyframeGraphMsg.msg
│ └── keyframeMsg.msg
├── package.xml
├── src
│ └── lsd_slam_pointcloud_publisher.cpp
└── thirdparty
│ └── Sophus
│ ├── CMakeLists.txt
│ ├── FindEigen3.cmake
│ ├── README
│ ├── SophusConfig.cmake.in
│ ├── cmake_modules
│ └── FindEigen3.cmake
│ └── sophus
│ ├── rxso3.hpp
│ ├── se2.hpp
│ ├── se3.hpp
│ ├── sim3.hpp
│ ├── so2.hpp
│ ├── so3.hpp
│ ├── sophus.hpp
│ ├── test_rxso3.cpp
│ ├── test_se2.cpp
│ ├── test_se3.cpp
│ ├── test_sim3.cpp
│ ├── test_so2.cpp
│ ├── test_so3.cpp
│ └── tests.hpp
└── visual_servo_control
├── CMakeLists.txt
├── include
└── visual_servo_control_node.h
├── package.xml
├── readme
├── src
├── cycle_node.cpp
└── visual_servo_control_node.cpp
└── srv
└── request_servo_velocity_vector.srv
/application_control/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.3)
2 |
3 | project(application_control)
4 |
5 | find_package(catkin REQUIRED COMPONENTS
6 | std_msgs
7 | message_generation
8 | roscpp
9 | tf
10 | baxter_core_msgs
11 | control_msgs
12 | actionlib_msgs
13 | genmsg
14 | actionlib
15 | image_transport
16 | cv_bridge
17 | )
18 |
19 | ## Specify additional locations of header files
20 | ## Your package locations should be listed before other locations
21 | include_directories($ENV{HALCONROOT}/include)
22 | include_directories($ENV{HALCONROOT}/include/halconcpp)
23 | include_directories($ENV{HALCONROOT}/include/hdevengine)
24 | include_directories(${catkin_INCLUDE_DIRS})
25 | include_directories(include)
26 |
27 |
28 | ## Generate messages in the 'msg' folder
29 | add_message_files(
30 | FILES
31 | State.msg
32 | changeState.msg
33 | )
34 |
35 | ## Generate services in the 'srv' folder
36 | add_service_files(
37 | FILES
38 | PauseRequest.srv
39 | request_camera_parameters.srv
40 | )
41 |
42 | ## Generate added messages and services with any dependencies listed here
43 | generate_messages(
44 | DEPENDENCIES
45 | std_msgs
46 | )
47 |
48 |
49 | catkin_package(
50 | DEPENDS yaml-cpp
51 | CATKIN_DEPENDS roscpp std_msgs control_msgs message_runtime
52 | )
53 |
54 | add_executable(application_control_node
55 | src/Main.cpp
56 | src/ColdBootState.cpp
57 | src/ReadyState.cpp
58 | src/MoveToHomeState.cpp
59 | src/ScanPlantState.cpp
60 | src/VisualServoState.cpp
61 | )
62 |
63 |
64 | link_directories(/opt/halcon/lib/x64-linux)
65 |
66 | include_directories(include ${catkin_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
67 |
68 | target_link_libraries(application_control_node yaml-cpp ${catkin_LIBRARIES})
69 | target_link_libraries(application_control_node $ENV{HALCONROOT}/lib/$ENV{HALCONARCH}/libhdevenginecpp.so ${catkin_LIBRARIES})
70 | target_link_libraries(application_control_node $ENV{HALCONROOT}/lib/$ENV{HALCONARCH}/libhalconcpp.so ${catkin_LIBRARIES})
71 | target_link_libraries(application_control_node $ENV{HALCONROOT}/lib/$ENV{HALCONARCH}/libhalcon.so ${catkin_LIBRARIES})
72 | target_link_libraries(application_control_node yaml-cpp ${catkin_LIBRARIES})
73 |
74 | add_dependencies(application_control_node ${catkin_EXPORTED_TARGETS})
75 |
76 | find_package(OpenCV REQUIRED)
77 | include_directories(${OpenCV_INCLUDE_DIRS})
78 | target_link_libraries(application_control_node ${OpenCV_LIBRARIES})
79 |
80 |
81 |
--------------------------------------------------------------------------------
/application_control/diagnostics/diagnostics_main.yaml:
--------------------------------------------------------------------------------
1 | pub_rate: 1.0 # Optional
2 | base_path: '' # Optional, prepended to all diagnostic output
3 | analyzers:
4 | State_machine: # Does not matter what name is used here (but avoid spaces!)
5 | type: diagnostic_aggregator/GenericAnalyzer # There are 4 different analyzer classes
6 | path: Main_control_program # This name will be displayed in the robot monitor
7 | startswith: Main_control_program # From the 'name' tag in the launch file
8 | find_and_remove_prefix: Main_control_program # Same name as above
9 |
10 | Error_handler:
11 | type: diagnostic_aggregator/GenericAnalyzer
12 | path: Error Manager
13 | startswith: Error_manager
14 | find_and_remove_prefix: Error_manager
15 |
16 |
17 | #Manipulator: # lets group everything concering the manpipulator here
18 | # type: AnalyzerGroup
19 | # path: Manipulator
20 | # analyzers:
21 | #Arm_controller:
22 | # type: diagnostic_aggregator/GenericAnalyzer
23 | # path: Manipulator controller
24 | # startswith: arm_control
25 | # find_and_remove_prefix: arm_control
26 |
27 | #Arm_UDP_interface:
28 | # type: diagnostic_aggregator/GenericAnalyzer
29 | # path: Arm UDP interface
30 | # startswith: crops_manipulator_udp
31 | # find_and_remove_prefix: crops_manipulator_udp
32 |
33 |
--------------------------------------------------------------------------------
/application_control/halcon_external_procedures/close_active_window.hdvp:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | dev_close_window ()
7 | return ()
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/application_control/halcon_external_procedures/find_area_pepper.hdvp:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | dev_update_off()
19 |
20 | * Decompose RGB in separate channels and transform this to Hue, Saturation and Intesity channels.
21 | *decompose3 (Image, ImageR, ImageG, ImageB)
22 | *trans_from_rgb (ImageR, ImageG, ImageB, ImageResultH, ImageResultS, ImageResultI, 'hsv')
23 | * Remove noise by smoothing the Hue channel.
24 | *gauss_image (ImageResultH, ImageGauss, 9)
25 | * Segment region in color range to get all red pixels in a range.
26 | *threshold (ImageGauss, Regions, HueLowerThreshold, HueUpperThreshold)
27 |
28 | * New segmentation in cielab.
29 | decompose3 (Image, ImageR, ImageG, ImageB)
30 | trans_from_rgb (ImageR, ImageG, ImageB, ImageResult1, ImageResult2, ImageResult3, 'cielab')
31 | threshold (ImageResult2, Regions, HueLowerThreshold, HueUpperThreshold)
32 |
33 | * Remove further small noise regions.
34 | erosion_circle (Regions, RegionErosion, 2)
35 | dilation_circle (RegionErosion, RegionDilation, 4)
36 |
37 | * Find connected components in the segmented regions.
38 | connection (RegionDilation, ConnectedRegions)
39 |
40 | count_obj (ConnectedRegions, NumberOfRegions)
41 | if(NumberOfRegions > 0)
42 | area_center (ConnectedRegions, Area, Row, Column)
43 | index_largest := -1
44 | area_largest := -1
45 | for i := 1 to NumberOfRegions by 1
46 |
47 | if (Area[i-1] > area_largest)
48 | index_largest := i
49 | area_largest := Area[i-1]
50 | endif
51 |
52 | endfor
53 | select_obj(ConnectedRegions, ObjectSelected, index_largest)
54 | area_center (ObjectSelected, Area_Object, raw_cog_y, raw_cog_x)
55 |
56 |
57 | dev_get_window (CurrentWindowID)
58 | if (CurrentWindowID != -1)
59 | dev_set_window(CurrentWindowID)
60 | dev_resize_window_fit_image (Image, 0, 0, -1, -1)
61 | dev_display (Image)
62 | dev_set_color ('red')
63 | dev_display(ObjectSelected)
64 | dev_update_off()
65 | else
66 | get_image_size (Image, Width, Height)
67 | dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
68 | dev_resize_window_fit_image (Image, 0, 0, -1, -1)
69 | dev_set_color ('red')
70 | dev_display(ObjectSelected)
71 | dev_display (Image)
72 | dev_update_off()
73 | endif
74 |
75 | else
76 | Area_Object := 0
77 | endif
78 |
79 | return ()
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/application_control/include/ColdBootState.h:
--------------------------------------------------------------------------------
1 | /*
2 | * ColdBoot.h
3 | */
4 |
5 | #ifndef COLDBOOT_H_
6 | #define COLDBOOT_H_
7 |
8 | #include "State.h"
9 | #include "ros/ros.h"
10 | #include "diagnostic_msgs/DiagnosticArray.h"
11 | #include "std_msgs/Bool.h"
12 | #include "baxter_core_msgs/AssemblyState.h"
13 |
14 | class ColdBootState : public State
15 | {
16 | private:
17 |
18 |
19 | public:
20 |
21 | ros::NodeHandle node_handle;
22 | ros::Publisher robot_activation;
23 | ros::Subscriber robot_state_subscriber;
24 | std::string transition_message;
25 | bool robot_state_enabled;
26 |
27 | void robotStateCallback(const baxter_core_msgs::AssemblyState::ConstPtr& state_msg);
28 | ColdBootState();
29 | std::string execute(std::map * data);
30 | };
31 |
32 | #endif /* COLDBOOT_H_ */
33 |
--------------------------------------------------------------------------------
/application_control/include/MoveToHomeState.h:
--------------------------------------------------------------------------------
1 | #ifndef MOVETOHOMESTATE_H_
2 | #define MOVETOHOMESTATE_H_
3 |
4 | #include "State.h"
5 | #include "ros/ros.h"
6 | #include "std_msgs/String.h"
7 | #include "baxter_core_msgs/EndpointState.h"
8 | #include "baxter_core_msgs/SolvePositionIK.h"
9 | #include "baxter_core_msgs/JointCommand.h"
10 | #include "geometry_msgs/Pose.h"
11 | #include "geometry_msgs/Point.h"
12 | #include "geometry_msgs/Quaternion.h"
13 | #include "geometry_msgs/PoseStamped.h"
14 | #include "sensor_msgs/JointState.h"
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 |
22 | class MoveToHomeState: public State {
23 |
24 | private:
25 | // Subscribers, Publishers, Clients, Listeners.
26 | tf::TransformListener transform_listener;
27 |
28 | // Global variables
29 | ros::NodeHandle node_handle;
30 | std::string transition;
31 | XmlRpc::XmlRpcValue home_position;
32 | bool first;
33 |
34 | public:
35 | void MoveToHome_Baxter();
36 |
37 | MoveToHomeState();
38 | std::string execute(std::map * data);
39 | };
40 |
41 | #endif /* MOVETOHOMESTATE_H_ */
42 |
--------------------------------------------------------------------------------
/application_control/include/ReadyState.h:
--------------------------------------------------------------------------------
1 | #ifndef READYSTATE_H_
2 | #define READYSTATE_H_
3 |
4 | #include "State.h"
5 | #include "ros/ros.h"
6 | #include "std_msgs/String.h"
7 |
8 | class ReadyState: public State {
9 | private:
10 | ros::NodeHandle node_handle;
11 | ros::Subscriber start_subscriber ;
12 | std::string transition;
13 | public:
14 | ReadyState();
15 | void startCallback(const std_msgs::String::ConstPtr& msg);
16 | std::string execute(std::map * data);
17 | };
18 |
19 | #endif /* READYSTATE_H_ */
20 |
--------------------------------------------------------------------------------
/application_control/include/ScanPlantState.h:
--------------------------------------------------------------------------------
1 | #ifndef SCANPLANTSTATE_H_
2 | #define SCANPLANTSTATE_H_
3 |
4 | //openCV FIRST, otherwise it does not compile. Do not ask why..
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #include "State.h"
11 | #include "ros/ros.h"
12 | #include "std_msgs/String.h"
13 | #include "baxter_core_msgs/EndpointState.h"
14 | #include "baxter_core_msgs/SolvePositionIK.h"
15 | #include "baxter_core_msgs/JointCommand.h"
16 | #include "geometry_msgs/Pose.h"
17 | #include "geometry_msgs/Point.h"
18 | #include "geometry_msgs/Quaternion.h"
19 | #include "geometry_msgs/PoseStamped.h"
20 | #include "sensor_msgs/JointState.h"
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include "HalconCpp.h"
29 | #include "HDevEngineCpp.h"
30 |
31 | #include
32 | #include
33 | #include
34 |
35 | class ScanPlantState: public State {
36 |
37 | private:
38 | // Subscribers, Publishers, Clients, Listeners.
39 | tf::TransformListener transform_listener;
40 | ros::ServiceClient image_client_rgb;
41 | ros::ServiceClient robot_endpointstate_client;
42 | ros::ServiceClient request_features_client;
43 | ros::Subscriber robot_endpoint_state_subscriber;
44 |
45 | // Global variables
46 | ros::NodeHandle node_handle;
47 | std::string transition;
48 | geometry_msgs::PoseStamped robot_endpoint_pose;
49 | bool first;
50 | XmlRpc::XmlRpcValue scan_waypoint_1;
51 | XmlRpc::XmlRpcValue scan_waypoint_2;
52 | XmlRpc::XmlRpcValue scan_waypoint_3;
53 | XmlRpc::XmlRpcValue scan_waypoint_4;
54 |
55 | HDevEngineCpp::HDevEngine hdevengine;
56 | std::string state_machine_halcon_external_procedures_path;
57 | std::string find_area_pepper_function;
58 | std::string close_window_function;
59 | int hue_lower_threshold;
60 | int hue_upper_threshold;
61 |
62 | struct detected_fruit {
63 | int area;
64 | geometry_msgs::PoseStamped pose;
65 | } ;
66 |
67 | std::vector detected_fruits;
68 | detected_fruit best_fruit;
69 |
70 |
71 | public:
72 |
73 | ScanPlantState();
74 | std::string execute(std::map * data);
75 | geometry_msgs::PoseStamped requestEndPointState();
76 | void EndpointStateCallback_Baxter(const baxter_core_msgs::EndpointState::ConstPtr& endpoint_msg);
77 | bool detectFruit();
78 | void closeWindow();
79 | std::string goToScanWaypoint(XmlRpc::XmlRpcValue waypoint);
80 | void setVisualServoStartingPose(std::map * data);
81 |
82 | };
83 |
84 | #endif /* SCANPLANTSTATE_H_ */
85 |
--------------------------------------------------------------------------------
/application_control/include/SimpleActionState.h:
--------------------------------------------------------------------------------
1 | /*
2 | * SimpleActionState.h
3 | *
4 | * Created on: Mar 1, 2012
5 | * Author: Peter Hohnloser
6 | */
7 |
8 | #ifndef SIMPLEACTIONSTATE_H_
9 | #define SIMPLEACTIONSTATE_H_
10 | #include
11 | #include
12 | #include
13 | #include "actionlib/client/simple_goal_state.h"
14 | #include "actionlib/client/simple_client_goal_state.h"
15 | #include
16 | #include
17 |
18 | using std::string;
19 |
20 | /* The class SimpleActionState is an abstract class which means
21 | * that another class has to inherit from it.
22 | */
23 |
24 | template
25 | class SimpleActionState : public State
26 | {
27 | protected:
28 | ACTION_DEFINITION(ASpec);
29 | typedef actionlib::SimpleActionClient client_;
30 | AGoal goal_;
31 | client_ ac_;
32 | bool first_;
33 | public:
34 | typedef boost::function
35 | SimpleDoneCallback;
36 | typedef boost::function SimpleFeedbackCallback;
37 | typedef boost::function SimpleActiveCallback;
38 |
39 | /*
40 | * Constructor needs the name of the SimpleActionServer node
41 | */
42 |
43 | SimpleActionState(string serverNode) :
44 | ac_(serverNode, true)
45 | {
46 | feedback_cb_ = SimpleFeedbackCallback();
47 | done_cb_ = SimpleDoneCallback();
48 | first_ = true;
49 | ROS_INFO("starting to wait for server %s",serverNode.c_str());
50 | ac_.waitForServer(ros::Duration(5));
51 | if (ac_.isServerConnected())
52 | ROS_INFO("connected to server %s",serverNode.c_str());
53 | else
54 | ROS_WARN("#GUI NOT!!! connected to server %s",serverNode.c_str());
55 |
56 | }
57 |
58 | virtual ~SimpleActionState()
59 | {
60 | }
61 | /**
62 | * sends the call to the SimpleActionServer
63 | */
64 | void sendGoal()
65 | {
66 | ac_.sendGoal(goal_, done_cb_, SimpleActiveCallback(), feedback_cb_);
67 | ac_.waitForResult(ros::Duration(0.1));
68 | }
69 | /**
70 | *
71 | */
72 | virtual bool setPause(bool p)
73 | {
74 | /*
75 | if (p)
76 | {
77 | if (!first_)
78 | {
79 | //ac_.cancelGoal();
80 | }
81 | }
82 | else
83 | {
84 | ac_.sendGoal(goal_, done_cb_, SimpleActiveCallback(), feedback_cb_);
85 | ac_.waitForResult(ros::Duration(0.1));
86 | }
87 | */
88 | mx.lock();
89 | pause = p;
90 | mx.unlock();
91 |
92 | return true;
93 | }
94 | /**
95 | * sets the feedback callback method for the SimpleActionCleint
96 | */
97 | void setFeedbackCallback(SimpleFeedbackCallback feedback_cb)
98 | {
99 | feedback_cb_ = feedback_cb;
100 | }
101 | /*
102 | * set the done callback method for the SimpleActinClient
103 | */
104 | void setDoneCallback(SimpleDoneCallback done_cb)
105 | {
106 | done_cb_ = done_cb;
107 | }
108 |
109 | void stop(){
110 | if(!first_)
111 | {
112 | ac_.cancelGoal();
113 | }
114 | first_ = true;
115 | }
116 |
117 | private:
118 | SimpleDoneCallback done_cb_;
119 | SimpleFeedbackCallback feedback_cb_;
120 | };
121 |
122 | #endif /* SIMPLEACTIONSTATE_H_ */
123 |
--------------------------------------------------------------------------------
/application_control/include/State.h:
--------------------------------------------------------------------------------
1 | /*
2 | * State.h
3 | *
4 | * Created on: Mar 1, 2012
5 | * Author: Peter Hohnloser
6 | */
7 | #ifndef STATE_H
8 | #define STATE_H
9 |
10 | #include
11 | #include "string.h"
12 | #include
13 | #include
14 |
15 |
16 | using std::string;
17 | using std::map;
18 | using boost::any;
19 | using boost::mutex;
20 | /*
21 | * The class state is an abstract class which means
22 | * that another class has to inherit from it.
23 | */
24 | class State
25 | {
26 | private:
27 | string state_name_;
28 | // ros::NodeHandle nh_;
29 |
30 | protected:
31 | bool pause;
32 | mutex mx;
33 | ros::Publisher stat_pub_;
34 | ros::NodeHandle nh_;
35 |
36 | public:
37 |
38 | /*
39 | *Constructs a state which is used by the state machine
40 | */
41 | State()
42 | {
43 | pause = false;
44 | mutex::scoped_lock mylock(mx, boost::defer_lock);
45 | }
46 | ;
47 |
48 | virtual ~State()
49 | {
50 | }
51 | ;
52 |
53 | /**
54 | * -------------------- These methods are used in the state machine-------
55 | */
56 |
57 | /*
58 | * Sets the name for the state.
59 | */
60 | void setStateName(string state_name)
61 | {
62 | state_name_ = state_name;
63 | }
64 | ;
65 | /*
66 | * returns the name of the state
67 | */
68 | string getStateName()
69 | {
70 | return state_name_;
71 | }
72 | ;
73 |
74 | /*
75 | * This method is needed in the state machine for executing a state.
76 | * This method must be implemented in the class which inherits from State.
77 | */
78 | virtual string execute(map * statedata)=0;
79 |
80 | /*
81 | * This method sets the state to pause.
82 | * It is possible to override this method for customize what happens when the state gets a pause request.
83 | */
84 | virtual bool setPause(bool p)
85 | {
86 | mx.lock();
87 | pause = p;
88 | mx.unlock();
89 | return true;
90 | }
91 | /**
92 | * This method returns true if the state is paused, otherwise false
93 | */
94 | bool getPause()
95 | {
96 | mx.lock();
97 | bool temp = pause;
98 | mx.unlock();
99 | return temp;
100 | }
101 |
102 | virtual void stop(){};
103 |
104 | };
105 |
106 | #endif
107 |
--------------------------------------------------------------------------------
/application_control/include/StateMachine.h:
--------------------------------------------------------------------------------
1 | /*
2 | * StateMachine.h
3 | *
4 | * Created on: Mar 1, 2012
5 | * Author: Peter Hohnloser
6 | */
7 | #ifndef STATEMACHINE_H
8 | #define STATEMACHINE_H
9 | #include