├── .gitignore
├── README.md
└── src
├── CMakeLists.txt
├── converter
├── CMakeLists.txt
├── CMakeLists.txt~
├── package.xml
├── package.xml~
└── src
│ └── image_converter.cpp
└── mycv
├── CMakeLists.txt
├── package.xml
└── src
└── image_converter.cpp
/.gitignore:
--------------------------------------------------------------------------------
1 | .cat*
2 | devel
3 | install
4 | build
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Autonomous Drone Capstone Project
2 | A senior capstone project by a Computer Science team at Miami University with the goal of programming a Bebop Drone to autonomously navigate a given space while searching for a goal.
3 |
4 | Result of this project available here: https://docs.google.com/document/d/1oVEO_3HxiXwagmXyrMhh8KIorxdNxHejzwBQ876_fpM/edit?usp=sharing
5 |
--------------------------------------------------------------------------------
/src/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | /opt/ros/indigo/share/catkin/cmake/toplevel.cmake
--------------------------------------------------------------------------------
/src/converter/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.3)
2 | project(converter)
3 |
4 | ## Add support for C++11, supported in ROS Kinetic and newer
5 | # add_definitions(-std=c++11)
6 |
7 | ## Find catkin macros and libraries
8 | ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
9 | ## is used, also find other catkin packages
10 | find_package(catkin REQUIRED COMPONENTS
11 | cv_bridge
12 | rospy
13 | sensor_msgs
14 | std_msgs
15 | image_transport
16 | )
17 |
18 | ## System dependencies are found with CMake's conventions
19 | # find_package(Boost REQUIRED COMPONENTS system)
20 |
21 |
22 | ## Uncomment this if the package has a setup.py. This macro ensures
23 | ## modules and global scripts declared therein get installed
24 | ## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
25 | # catkin_python_setup()
26 |
27 | ################################################
28 | ## Declare ROS messages, services and actions ##
29 | ################################################
30 |
31 | ## To declare and build messages, services or actions from within this
32 | ## package, follow these steps:
33 | ## * Let MSG_DEP_SET be the set of packages whose message types you use in
34 | ## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
35 | ## * In the file package.xml:
36 | ## * add a build_depend tag for "message_generation"
37 | ## * add a build_depend and a run_depend tag for each package in MSG_DEP_SET
38 | ## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
39 | ## but can be declared for certainty nonetheless:
40 | ## * add a run_depend tag for "message_runtime"
41 | ## * In this file (CMakeLists.txt):
42 | ## * add "message_generation" and every package in MSG_DEP_SET to
43 | ## find_package(catkin REQUIRED COMPONENTS ...)
44 | ## * add "message_runtime" and every package in MSG_DEP_SET to
45 | ## catkin_package(CATKIN_DEPENDS ...)
46 | ## * uncomment the add_*_files sections below as needed
47 | ## and list every .msg/.srv/.action file to be processed
48 | ## * uncomment the generate_messages entry below
49 | ## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
50 |
51 | ## Generate messages in the 'msg' folder
52 | # add_message_files(
53 | # FILES
54 | # Message1.msg
55 | # Message2.msg
56 | # )
57 |
58 | ## Generate services in the 'srv' folder
59 | # add_service_files(
60 | # FILES
61 | # Service1.srv
62 | # Service2.srv
63 | # )
64 |
65 | ## Generate actions in the 'action' folder
66 | # add_action_files(
67 | # FILES
68 | # Action1.action
69 | # Action2.action
70 | # )
71 |
72 | ## Generate added messages and services with any dependencies listed here
73 | # generate_messages(
74 | # DEPENDENCIES
75 | # sensor_msgs# std_msgs
76 | # )
77 |
78 | ################################################
79 | ## Declare ROS dynamic reconfigure parameters ##
80 | ################################################
81 |
82 | ## To declare and build dynamic reconfigure parameters within this
83 | ## package, follow these steps:
84 | ## * In the file package.xml:
85 | ## * add a build_depend and a run_depend tag for "dynamic_reconfigure"
86 | ## * In this file (CMakeLists.txt):
87 | ## * add "dynamic_reconfigure" to
88 | ## find_package(catkin REQUIRED COMPONENTS ...)
89 | ## * uncomment the "generate_dynamic_reconfigure_options" section below
90 | ## and list every .cfg file to be processed
91 |
92 | ## Generate dynamic reconfigure parameters in the 'cfg' folder
93 | # generate_dynamic_reconfigure_options(
94 | # cfg/DynReconf1.cfg
95 | # cfg/DynReconf2.cfg
96 | # )
97 |
98 | ###################################
99 | ## catkin specific configuration ##
100 | ###################################
101 | ## The catkin_package macro generates cmake config files for your package
102 | ## Declare things to be passed to dependent projects
103 | ## INCLUDE_DIRS: uncomment this if you package contains header files
104 | ## LIBRARIES: libraries you create in this project that dependent projects also need
105 | ## CATKIN_DEPENDS: catkin_packages dependent projects also need
106 | ## DEPENDS: system dependencies of this project that dependent projects also need
107 | catkin_package(
108 | # INCLUDE_DIRS include
109 | # LIBRARIES converter
110 | # CATKIN_DEPENDS cv_bridge rospy sensor_msgs std_msgs
111 | # DEPENDS system_lib
112 | )
113 |
114 | ###########
115 | ## Build ##
116 | ###########
117 |
118 | ## Specify additional locations of header files
119 | ## Your package locations should be listed before other locations
120 | # include_directories(include)
121 | include_directories(
122 | ${catkin_INCLUDE_DIRS}
123 | )
124 |
125 | ## Declare a C++ library
126 | # add_library(${PROJECT_NAME}
127 | # src/${PROJECT_NAME}/mycv.cpp
128 | # )
129 |
130 | ## Add cmake target dependencies of the library
131 | ## as an example, code may need to be generated before libraries
132 | ## either from message generation or dynamic reconfigure
133 | # add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
134 |
135 | ## Declare a C++ executable
136 | ## With catkin_make all packages are built within a single CMake context
137 | ## The recommended prefix ensures that target names across packages don't collide
138 |
139 | add_executable(${PROJECT_NAME}_node src/image_converter.cpp)
140 |
141 | ## Rename C++ executable without prefix
142 | ## The above recommended prefix causes long target names, the following renames the
143 | ## target back to the shorter version for ease of user use
144 | ## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
145 | # set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
146 |
147 | ## Add cmake target dependencies of the executable
148 | ## same as for the library above
149 | add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
150 |
151 | ## Specify libraries to link a library or executable target against
152 | target_link_libraries(${PROJECT_NAME}_node
153 | ${catkin_LIBRARIES}
154 | )
155 |
156 | #############
157 | ## Install ##
158 | #############
159 |
160 | # all install targets should use catkin DESTINATION variables
161 | # See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
162 |
163 | ## Mark executable scripts (Python etc.) for installation
164 | ## in contrast to setup.py, you can choose the destination
165 | # install(PROGRAMS
166 | # scripts/my_python_script
167 | # DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
168 | # )
169 |
170 | ## Mark executables and/or libraries for installation
171 | # install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_node
172 | # ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
173 | # LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
174 | # RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
175 | # )
176 |
177 | ## Mark cpp header files for installation
178 | # install(DIRECTORY include/${PROJECT_NAME}/
179 | # DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
180 | # FILES_MATCHING PATTERN "*.h"
181 | # PATTERN ".svn" EXCLUDE
182 | # )
183 |
184 | ## Mark other files for installation (e.g. launch and bag files, etc.)
185 | # install(FILES
186 | # # myfile1
187 | # # myfile2
188 | # DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
189 | # )
190 |
191 | #############
192 | ## Testing ##
193 | #############
194 |
195 | ## Add gtest based cpp test target and link libraries
196 | # catkin_add_gtest(${PROJECT_NAME}-test test/test_mycv.cpp)
197 | # if(TARGET ${PROJECT_NAME}-test)
198 | # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
199 | # endif()
200 |
201 | ## Add folders to be run by python nosetests
202 | # catkin_add_nosetests(test)
203 |
--------------------------------------------------------------------------------
/src/converter/CMakeLists.txt~:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.3)
2 | project(converter)
3 |
4 | ## Add support for C++11, supported in ROS Kinetic and newer
5 | # add_definitions(-std=c++11)
6 |
7 | ## Find catkin macros and libraries
8 | ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
9 | ## is used, also find other catkin packages
10 | find_package(catkin REQUIRED COMPONENTS
11 | cv_bridge
12 | rospy
13 | sensor_msgs
14 | std_msgs
15 | image_transport
16 | )
17 |
18 | ## System dependencies are found with CMake's conventions
19 | # find_package(Boost REQUIRED COMPONENTS system)
20 |
21 |
22 | ## Uncomment this if the package has a setup.py. This macro ensures
23 | ## modules and global scripts declared therein get installed
24 | ## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
25 | # catkin_python_setup()
26 |
27 | ################################################
28 | ## Declare ROS messages, services and actions ##
29 | ################################################
30 |
31 | ## To declare and build messages, services or actions from within this
32 | ## package, follow these steps:
33 | ## * Let MSG_DEP_SET be the set of packages whose message types you use in
34 | ## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
35 | ## * In the file package.xml:
36 | ## * add a build_depend tag for "message_generation"
37 | ## * add a build_depend and a run_depend tag for each package in MSG_DEP_SET
38 | ## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
39 | ## but can be declared for certainty nonetheless:
40 | ## * add a run_depend tag for "message_runtime"
41 | ## * In this file (CMakeLists.txt):
42 | ## * add "message_generation" and every package in MSG_DEP_SET to
43 | ## find_package(catkin REQUIRED COMPONENTS ...)
44 | ## * add "message_runtime" and every package in MSG_DEP_SET to
45 | ## catkin_package(CATKIN_DEPENDS ...)
46 | ## * uncomment the add_*_files sections below as needed
47 | ## and list every .msg/.srv/.action file to be processed
48 | ## * uncomment the generate_messages entry below
49 | ## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
50 |
51 | ## Generate messages in the 'msg' folder
52 | # add_message_files(
53 | # FILES
54 | # Message1.msg
55 | # Message2.msg
56 | # )
57 |
58 | ## Generate services in the 'srv' folder
59 | # add_service_files(
60 | # FILES
61 | # Service1.srv
62 | # Service2.srv
63 | # )
64 |
65 | ## Generate actions in the 'action' folder
66 | # add_action_files(
67 | # FILES
68 | # Action1.action
69 | # Action2.action
70 | # )
71 |
72 | ## Generate added messages and services with any dependencies listed here
73 | # generate_messages(
74 | # DEPENDENCIES
75 | # sensor_msgs# std_msgs
76 | # )
77 |
78 | ################################################
79 | ## Declare ROS dynamic reconfigure parameters ##
80 | ################################################
81 |
82 | ## To declare and build dynamic reconfigure parameters within this
83 | ## package, follow these steps:
84 | ## * In the file package.xml:
85 | ## * add a build_depend and a run_depend tag for "dynamic_reconfigure"
86 | ## * In this file (CMakeLists.txt):
87 | ## * add "dynamic_reconfigure" to
88 | ## find_package(catkin REQUIRED COMPONENTS ...)
89 | ## * uncomment the "generate_dynamic_reconfigure_options" section below
90 | ## and list every .cfg file to be processed
91 |
92 | ## Generate dynamic reconfigure parameters in the 'cfg' folder
93 | # generate_dynamic_reconfigure_options(
94 | # cfg/DynReconf1.cfg
95 | # cfg/DynReconf2.cfg
96 | # )
97 |
98 | ###################################
99 | ## catkin specific configuration ##
100 | ###################################
101 | ## The catkin_package macro generates cmake config files for your package
102 | ## Declare things to be passed to dependent projects
103 | ## INCLUDE_DIRS: uncomment this if you package contains header files
104 | ## LIBRARIES: libraries you create in this project that dependent projects also need
105 | ## CATKIN_DEPENDS: catkin_packages dependent projects also need
106 | ## DEPENDS: system dependencies of this project that dependent projects also need
107 | catkin_package(
108 | # INCLUDE_DIRS include
109 | # LIBRARIES mycv
110 | # CATKIN_DEPENDS cv_bridge rospy sensor_msgs std_msgs
111 | # DEPENDS system_lib
112 | )
113 |
114 | ###########
115 | ## Build ##
116 | ###########
117 |
118 | ## Specify additional locations of header files
119 | ## Your package locations should be listed before other locations
120 | # include_directories(include)
121 | include_directories(
122 | ${catkin_INCLUDE_DIRS}
123 | )
124 |
125 | ## Declare a C++ library
126 | # add_library(${PROJECT_NAME}
127 | # src/${PROJECT_NAME}/mycv.cpp
128 | # )
129 |
130 | ## Add cmake target dependencies of the library
131 | ## as an example, code may need to be generated before libraries
132 | ## either from message generation or dynamic reconfigure
133 | # add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
134 |
135 | ## Declare a C++ executable
136 | ## With catkin_make all packages are built within a single CMake context
137 | ## The recommended prefix ensures that target names across packages don't collide
138 |
139 | add_executable(${PROJECT_NAME}_node src/image_converter.cpp)
140 |
141 | ## Rename C++ executable without prefix
142 | ## The above recommended prefix causes long target names, the following renames the
143 | ## target back to the shorter version for ease of user use
144 | ## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
145 | # set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
146 |
147 | ## Add cmake target dependencies of the executable
148 | ## same as for the library above
149 | add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
150 |
151 | ## Specify libraries to link a library or executable target against
152 | target_link_libraries(${PROJECT_NAME}_node
153 | ${catkin_LIBRARIES}
154 | )
155 |
156 | #############
157 | ## Install ##
158 | #############
159 |
160 | # all install targets should use catkin DESTINATION variables
161 | # See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
162 |
163 | ## Mark executable scripts (Python etc.) for installation
164 | ## in contrast to setup.py, you can choose the destination
165 | # install(PROGRAMS
166 | # scripts/my_python_script
167 | # DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
168 | # )
169 |
170 | ## Mark executables and/or libraries for installation
171 | # install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_node
172 | # ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
173 | # LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
174 | # RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
175 | # )
176 |
177 | ## Mark cpp header files for installation
178 | # install(DIRECTORY include/${PROJECT_NAME}/
179 | # DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
180 | # FILES_MATCHING PATTERN "*.h"
181 | # PATTERN ".svn" EXCLUDE
182 | # )
183 |
184 | ## Mark other files for installation (e.g. launch and bag files, etc.)
185 | # install(FILES
186 | # # myfile1
187 | # # myfile2
188 | # DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
189 | # )
190 |
191 | #############
192 | ## Testing ##
193 | #############
194 |
195 | ## Add gtest based cpp test target and link libraries
196 | # catkin_add_gtest(${PROJECT_NAME}-test test/test_mycv.cpp)
197 | # if(TARGET ${PROJECT_NAME}-test)
198 | # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
199 | # endif()
200 |
201 | ## Add folders to be run by python nosetests
202 | # catkin_add_nosetests(test)
203 |
--------------------------------------------------------------------------------
/src/converter/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | converter
4 | 0.0.0
5 | Converts bebop video source into a different resolution
6 |
7 |
8 |
9 |
10 | Matt DePero
11 |
12 |
13 |
14 |
15 |
16 | IDK
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | catkin
43 | cv_bridge
44 | rospy
45 | sensor_msgs
46 | std_msgs
47 | image_transport
48 | image_transport
49 | cv_bridge
50 | rospy
51 | sensor_msgs
52 | std_msgs
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/src/converter/package.xml~:
--------------------------------------------------------------------------------
1 |
2 |
3 | coverter
4 | 0.0.0
5 | Converts bebop video source into a different resolution
6 |
7 |
8 |
9 |
10 | Matt DePero
11 |
12 |
13 |
14 |
15 |
16 | IDK
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | catkin
43 | cv_bridge
44 | rospy
45 | sensor_msgs
46 | std_msgs
47 | image_transport
48 | image_transport
49 | cv_bridge
50 | rospy
51 | sensor_msgs
52 | std_msgs
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/src/converter/src/image_converter.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | static const std::string OPENCV_WINDOW = "Image window";
9 |
10 | class ImageConverter
11 | {
12 | ros::NodeHandle nh_;
13 | image_transport::ImageTransport it_;
14 | image_transport::Subscriber image_sub_;
15 | image_transport::Publisher image_pub_;
16 |
17 | ros::Publisher cam_info_pub;
18 | ros::Subscriber cam_sub;
19 |
20 | public:
21 | ImageConverter()
22 | : it_(nh_)
23 | {
24 | // Subscrive to input video feed and publish output video feed
25 | image_sub_ = it_.subscribe("/image_raw", 1,
26 | &ImageConverter::imageCb, this);
27 | image_pub_ = it_.advertise("/image_converter/output_video", 1);
28 |
29 | cam_info_pub = nh_.advertise("/resized_cam_info", 1000);
30 | cam_sub = nh_.subscribe("/camera_info", 1000, &ImageConverter::cam_info_callback, this);
31 |
32 | cv::namedWindow(OPENCV_WINDOW);
33 | }
34 |
35 | ~ImageConverter()
36 | {
37 | cv::destroyWindow(OPENCV_WINDOW);
38 | }
39 |
40 | void cam_info_callback(const sensor_msgs::CameraInfo::ConstPtr& msg) {
41 |
42 | sensor_msgs::CameraInfo newMsg = *msg;
43 |
44 | // printf("tester %d\n",newMsg.width);
45 |
46 | newMsg.width = 640;
47 | newMsg.height = 480;
48 |
49 | cam_info_pub.publish(newMsg);
50 |
51 | }
52 |
53 | void imageCb(const sensor_msgs::ImageConstPtr& msg)
54 | {
55 | cv_bridge::CvImagePtr cv_ptr;
56 | try
57 | {
58 | cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::MONO8);
59 | }
60 | catch (cv_bridge::Exception& e)
61 | {
62 | ROS_ERROR("cv_bridge exception: %s", e.what());
63 | return;
64 | }
65 |
66 | // Draw an example circle on the video stream
67 | // if (cv_ptr->image.rows > 60 && cv_ptr->image.cols > 60)
68 | // cv::circle(cv_ptr->image, cv::Point(50, 50), 10, CV_RGB(255,0,0));
69 |
70 | /* ============= START RESIZE FUNCTION THING ============ */
71 |
72 | cv::Mat resized;
73 | cv::Size size(640,480);
74 | cv::resize(cv_ptr->image, resized, size);
75 |
76 | // Update GUI Window
77 | cv::imshow(OPENCV_WINDOW, resized);
78 | cv_ptr->image = resized;
79 | cv::waitKey(3);
80 |
81 | // Output modified video stream
82 | image_pub_.publish(cv_ptr->toImageMsg());
83 | }
84 | };
85 |
86 | int main(int argc, char** argv)
87 | {
88 | ros::init(argc, argv, "image_converter");
89 | ImageConverter ic;
90 | ros::spin();
91 | return 0;
92 | }
93 |
94 |
--------------------------------------------------------------------------------
/src/mycv/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.3)
2 | project(mycv)
3 |
4 | ## Add support for C++11, supported in ROS Kinetic and newer
5 | # add_definitions(-std=c++11)
6 |
7 | ## Find catkin macros and libraries
8 | ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
9 | ## is used, also find other catkin packages
10 | find_package(catkin REQUIRED COMPONENTS
11 | cv_bridge
12 | rospy
13 | sensor_msgs
14 | std_msgs
15 | image_transport
16 | geometry_msgs
17 | )
18 |
19 | ## System dependencies are found with CMake's conventions
20 | # find_package(Boost REQUIRED COMPONENTS system)
21 |
22 |
23 | ## Uncomment this if the package has a setup.py. This macro ensures
24 | ## modules and global scripts declared therein get installed
25 | ## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
26 | # catkin_python_setup()
27 |
28 | ################################################
29 | ## Declare ROS messages, services and actions ##
30 | ################################################
31 |
32 | ## To declare and build messages, services or actions from within this
33 | ## package, follow these steps:
34 | ## * Let MSG_DEP_SET be the set of packages whose message types you use in
35 | ## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
36 | ## * In the file package.xml:
37 | ## * add a build_depend tag for "message_generation"
38 | ## * add a build_depend and a run_depend tag for each package in MSG_DEP_SET
39 | ## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
40 | ## but can be declared for certainty nonetheless:
41 | ## * add a run_depend tag for "message_runtime"
42 | ## * In this file (CMakeLists.txt):
43 | ## * add "message_generation" and every package in MSG_DEP_SET to
44 | ## find_package(catkin REQUIRED COMPONENTS ...)
45 | ## * add "message_runtime" and every package in MSG_DEP_SET to
46 | ## catkin_package(CATKIN_DEPENDS ...)
47 | ## * uncomment the add_*_files sections below as needed
48 | ## and list every .msg/.srv/.action file to be processed
49 | ## * uncomment the generate_messages entry below
50 | ## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
51 |
52 | ## Generate messages in the 'msg' folder
53 | # add_message_files(
54 | # FILES
55 | # Message1.msg
56 | # Message2.msg
57 | # )
58 |
59 | ## Generate services in the 'srv' folder
60 | # add_service_files(
61 | # FILES
62 | # Service1.srv
63 | # Service2.srv
64 | # )
65 |
66 | ## Generate actions in the 'action' folder
67 | # add_action_files(
68 | # FILES
69 | # Action1.action
70 | # Action2.action
71 | # )
72 |
73 | ## Generate added messages and services with any dependencies listed here
74 | # generate_messages(
75 | # DEPENDENCIES
76 | # sensor_msgs# std_msgs
77 | # )
78 |
79 | ################################################
80 | ## Declare ROS dynamic reconfigure parameters ##
81 | ################################################
82 |
83 | ## To declare and build dynamic reconfigure parameters within this
84 | ## package, follow these steps:
85 | ## * In the file package.xml:
86 | ## * add a build_depend and a run_depend tag for "dynamic_reconfigure"
87 | ## * In this file (CMakeLists.txt):
88 | ## * add "dynamic_reconfigure" to
89 | ## find_package(catkin REQUIRED COMPONENTS ...)
90 | ## * uncomment the "generate_dynamic_reconfigure_options" section below
91 | ## and list every .cfg file to be processed
92 |
93 | ## Generate dynamic reconfigure parameters in the 'cfg' folder
94 | # generate_dynamic_reconfigure_options(
95 | # cfg/DynReconf1.cfg
96 | # cfg/DynReconf2.cfg
97 | # )
98 |
99 | ###################################
100 | ## catkin specific configuration ##
101 | ###################################
102 | ## The catkin_package macro generates cmake config files for your package
103 | ## Declare things to be passed to dependent projects
104 | ## INCLUDE_DIRS: uncomment this if you package contains header files
105 | ## LIBRARIES: libraries you create in this project that dependent projects also need
106 | ## CATKIN_DEPENDS: catkin_packages dependent projects also need
107 | ## DEPENDS: system dependencies of this project that dependent projects also need
108 | catkin_package(
109 | # INCLUDE_DIRS include
110 | # LIBRARIES mycv
111 | # CATKIN_DEPENDS cv_bridge rospy sensor_msgs std_msgs
112 | # DEPENDS system_lib
113 | )
114 |
115 | ###########
116 | ## Build ##
117 | ###########
118 |
119 | ## Specify additional locations of header files
120 | ## Your package locations should be listed before other locations
121 | # include_directories(include)
122 | include_directories(
123 | ${catkin_INCLUDE_DIRS}
124 | )
125 |
126 | ## Declare a C++ library
127 | # add_library(${PROJECT_NAME}
128 | # src/${PROJECT_NAME}/mycv.cpp
129 | # )
130 |
131 | ## Add cmake target dependencies of the library
132 | ## as an example, code may need to be generated before libraries
133 | ## either from message generation or dynamic reconfigure
134 | # add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
135 |
136 | ## Declare a C++ executable
137 | ## With catkin_make all packages are built within a single CMake context
138 | ## The recommended prefix ensures that target names across packages don't collide
139 |
140 | add_executable(${PROJECT_NAME}_node src/image_converter.cpp)
141 |
142 | ## Rename C++ executable without prefix
143 | ## The above recommended prefix causes long target names, the following renames the
144 | ## target back to the shorter version for ease of user use
145 | ## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
146 | # set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
147 |
148 | ## Add cmake target dependencies of the executable
149 | ## same as for the library above
150 | add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
151 |
152 | ## Specify libraries to link a library or executable target against
153 | target_link_libraries(${PROJECT_NAME}_node
154 | ${catkin_LIBRARIES}
155 | )
156 |
157 | #############
158 | ## Install ##
159 | #############
160 |
161 | # all install targets should use catkin DESTINATION variables
162 | # See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
163 |
164 | ## Mark executable scripts (Python etc.) for installation
165 | ## in contrast to setup.py, you can choose the destination
166 | # install(PROGRAMS
167 | # scripts/my_python_script
168 | # DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
169 | # )
170 |
171 | ## Mark executables and/or libraries for installation
172 | # install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_node
173 | # ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
174 | # LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
175 | # RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
176 | # )
177 |
178 | ## Mark cpp header files for installation
179 | # install(DIRECTORY include/${PROJECT_NAME}/
180 | # DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
181 | # FILES_MATCHING PATTERN "*.h"
182 | # PATTERN ".svn" EXCLUDE
183 | # )
184 |
185 | ## Mark other files for installation (e.g. launch and bag files, etc.)
186 | # install(FILES
187 | # # myfile1
188 | # # myfile2
189 | # DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
190 | # )
191 |
192 | #############
193 | ## Testing ##
194 | #############
195 |
196 | ## Add gtest based cpp test target and link libraries
197 | # catkin_add_gtest(${PROJECT_NAME}-test test/test_mycv.cpp)
198 | # if(TARGET ${PROJECT_NAME}-test)
199 | # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
200 | # endif()
201 |
202 | ## Add folders to be run by python nosetests
203 | # catkin_add_nosetests(test)
204 |
--------------------------------------------------------------------------------
/src/mycv/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | mycv
4 | 0.0.0
5 | A test package for openCV use with ROS and a parot Bebop
6 |
7 |
8 |
9 |
10 | Matt DePero
11 |
12 |
13 |
14 |
15 |
16 | IDK
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | catkin
43 | cv_bridge
44 | rospy
45 | sensor_msgs
46 | std_msgs
47 | image_transport
48 | geometry_msgs
49 | image_transport
50 | cv_bridge
51 | rospy
52 | sensor_msgs
53 | std_msgs
54 | geometry_msgs
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/src/mycv/src/image_converter.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 |
10 | static const std::string INPUT_WINDOW = "OpenCV Input Image";
11 | static const std::string HSV_WINDOW = "OpenCV HSV Image";
12 | static const std::string THRESH_WINDOW = "OpenCV Threshold Image";
13 |
14 | using namespace cv;
15 |
16 | class ImageConverter
17 | {
18 | ros::NodeHandle nh_;
19 | image_transport::ImageTransport it_;
20 | image_transport::Subscriber image_sub_;
21 | image_transport::Publisher image_pub_;
22 |
23 | geometry_msgs::Twist command;
24 |
25 | ros::Publisher twist_pub_;
26 |
27 | double cam_x;
28 |
29 | // ranges in HSV color space attempting to find target color
30 | /* GREEN (many false positives)
31 | static const int H_MIN = 0;
32 | static const int H_MAX = 100;
33 | static const int S_MIN = 140;
34 | static const int S_MAX = 190;
35 | static const int V_MIN = 140;
36 | static const int V_MAX = 220;
37 | */
38 |
39 | /* ORANGE */
40 | static const int H_MIN = 5;
41 | static const int H_MAX = 16;
42 | static const int S_MIN = 100;
43 | static const int S_MAX = 200;
44 | static const int V_MIN = 178;
45 | static const int V_MAX = 255;
46 |
47 | static const double CAM_SPEED = .10;
48 | static const int DEAD_ZONE = 120;
49 | static const double SPEEDUP_FACTOR = .002;
50 |
51 | static const int MAX_NUM_OBJECTS=3;
52 | static const int MIN_OBJECT_AREA = 20*20; // must be at least 20x20 pixels
53 | static const int MAX_OBJECT_AREA = 70*70; // don't care how big it is
54 |
55 | static const bool DEBUG_COLOR_VALUES = 0; // print color values at pixel at 1, 1 (top left corner)
56 | static const bool SHOW_WINDOWS = 0; // used to turn off the displays in a docker image
57 | static const bool SHOW_TURN_VALUES = 1; // print turn weights in real time
58 | public:
59 | ImageConverter()
60 | : it_(nh_)
61 | {
62 | // Subscrive to input video feed and publish output video feed
63 | image_sub_ = it_.subscribe("/bebop/image_raw", 1,
64 | &ImageConverter::imageCb, this);
65 | image_pub_ = it_.advertise("/image_converter/output_video", 1);
66 |
67 |
68 | twist_pub_ = nh_.advertise("bebop/cmd_vel", 1);
69 |
70 | cam_x = -0;
71 |
72 | if(SHOW_WINDOWS){
73 | cv::namedWindow(INPUT_WINDOW);
74 | cv::namedWindow(HSV_WINDOW);
75 | cv::namedWindow(THRESH_WINDOW);
76 | }
77 | }
78 |
79 | ~ImageConverter()
80 | {
81 | if(SHOW_WINDOWS){
82 | cv::destroyWindow(INPUT_WINDOW);
83 | cv::destroyWindow(HSV_WINDOW);
84 | cv::destroyWindow(THRESH_WINDOW);
85 | }
86 | }
87 |
88 | // method from https://www.youtube.com/watch?v=bSeFrPrqZ2A
89 | void morphOps(cv::Mat &thresh){
90 |
91 | //create structuring element that will be used to "dilate" and "erode" image.
92 | //the element chosen here is a 3px by 3px rectangle
93 |
94 | cv::Mat erodeElement = cv::getStructuringElement( cv::MORPH_RECT,cv::Size(5,5));
95 | //dilate with larger element so make sure object is nicely visible
96 | cv::Mat dilateElement = cv::getStructuringElement( cv::MORPH_RECT,cv::Size(8,8));
97 |
98 | cv::erode(thresh,thresh,erodeElement);
99 | cv::erode(thresh,thresh,erodeElement);
100 |
101 |
102 | cv::dilate(thresh,thresh,dilateElement);
103 | cv::dilate(thresh,thresh,dilateElement);
104 |
105 | }
106 | // method from https://www.youtube.com/watch?v=bSeFrPrqZ2A
107 | string intToString(int number){
108 |
109 |
110 | std::stringstream ss;
111 | ss << number;
112 | return ss.str();
113 | }
114 | // method from https://www.youtube.com/watch?v=bSeFrPrqZ2A
115 | void drawObject(int x, int y,Mat &frame){
116 |
117 | //use some of the openCV drawing functions to draw crosshairs
118 | //on your tracked image!
119 |
120 | //UPDATE:JUNE 18TH, 2013
121 | //added 'if' and 'else' statements to prevent
122 | //memory errors from writing off the screen (ie. (-25,-25) is not within the window!)
123 |
124 | circle(frame,Point(x,y),20,Scalar(0,255,0),2);
125 | if(y-25>0)
126 | line(frame,Point(x,y),Point(x,y-25),Scalar(0,255,0),2);
127 | else line(frame,Point(x,y),Point(x,0),Scalar(0,255,0),2);
128 | if(y+250)
132 | line(frame,Point(x,y),Point(x-25,y),Scalar(0,255,0),2);
133 | else line(frame,Point(x,y),Point(0,y),Scalar(0,255,0),2);
134 | if(x+25 > contours;
149 | vector hierarchy;
150 | //find contours of filtered image using openCV findContours function
151 | findContours(temp,contours,hierarchy,CV_RETR_CCOMP,CV_CHAIN_APPROX_SIMPLE );
152 | //use moments method to find our filtered object
153 | double refArea = 0;
154 | bool objectFound = false;
155 | if (hierarchy.size() > 0) {
156 | int numObjects = hierarchy.size();
157 | //if number of objects greater than MAX_NUM_OBJECTS we have a noisy filter
158 | if(numObjects<=MAX_NUM_OBJECTS){
159 | for (int index = 0; index >= 0; index = hierarchy[index][0]) {
160 |
161 | Moments moment = moments((cv::Mat)contours[index]);
162 | double area = moment.m00;
163 |
164 | //if the area is less than 20 px by 20px then it is probably just noise
165 | //if the area is the same as the 3/2 of the image size, probably just a bad filter
166 | //we only want the object with the largest area so we safe a reference area each
167 | //iteration and compare it to the area in the next iteration.
168 | if(area>MIN_OBJECT_AREA && arearefArea){
169 | x = moment.m10/area;
170 | y = moment.m01/area;
171 | objectFound = true;
172 | refArea = area;
173 | }else objectFound = false;
174 |
175 |
176 | }
177 | //let user know you found an object
178 | if(objectFound ==true){
179 | putText(cameraFeed,"Goal Detected!",Point(0,50),2,1,Scalar(0,255,0),2);
180 | //draw object location on screen
181 | drawObject(x,y,cameraFeed);}
182 |
183 | }else putText(cameraFeed,"TOO MUCH NOISE!",Point(0,50),1,2,Scalar(0,0,255),2);
184 | }
185 | }
186 |
187 | void imageCb(const sensor_msgs::ImageConstPtr& msg)
188 | {
189 | cv_bridge::CvImagePtr cv_ptr;
190 | try
191 | {
192 | cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
193 | }
194 | catch (cv_bridge::Exception& e)
195 | {
196 | ROS_ERROR("cv_bridge exception: %s", e.what());
197 | return;
198 | }
199 |
200 |
201 | /* ==== MAKE VARIABLES ==== */
202 |
203 | // place holders for incoming original image, that image converted into HSV, and the HSV image filtered by thresholds to create a binary map searching for target color
204 | cv::Mat input = cv_ptr->image, hsv_image, threshold;
205 |
206 | int x=0, y=0;
207 |
208 | /* ==== DO STUFF ==== */
209 |
210 | // convert input into HSV color space
211 | cv::cvtColor(input, hsv_image, cv::COLOR_BGR2HSV);
212 | // convert HSV image into binary map attempting to find target color
213 | cv::inRange(hsv_image,cv::Scalar(H_MIN,S_MIN,V_MIN),cv::Scalar(H_MAX,S_MAX,V_MAX),threshold);
214 |
215 | // erode and dialte to remove noise from the image
216 | morphOps(threshold);
217 |
218 | // search the image for objects
219 | trackFilteredObject(x, y, threshold, input);
220 |
221 | // Debug: printing the color in the top left corner of the image
222 | if(DEBUG_COLOR_VALUES){
223 | cv::Vec3b pixel = hsv_image.at(1, 1);
224 | printf("H=%d, S=%d, V=%d\n", pixel[0], pixel[1], pixel[2]);
225 | }
226 |
227 | if (x && y) {
228 |
229 | if ( x < (threshold.cols / 2 - DEAD_ZONE) ) {
230 | if(SHOW_TURN_VALUES)
231 | printf("Move left %f",cam_x);
232 | cam_x = CAM_SPEED;
233 |
234 | } else if ( x > (threshold.cols / 2 + DEAD_ZONE) ){
235 | if(SHOW_TURN_VALUES)
236 | printf("Move right %f",cam_x);
237 | cam_x = -CAM_SPEED;
238 |
239 | } else {
240 |
241 | cam_x = 0; // dead zone
242 |
243 | }
244 |
245 | double speedup = (x - (threshold.cols/2) ) * SPEEDUP_FACTOR;
246 |
247 | command.angular.z = cam_x - speedup;
248 |
249 | printf("%f \n", speedup);
250 | twist_pub_.publish(command);
251 |
252 |
253 | }
254 |
255 | /* ==== UPDATE GUI'S ==== */
256 | if(SHOW_WINDOWS){
257 | cv::imshow(INPUT_WINDOW, input);
258 | cv::imshow(HSV_WINDOW, hsv_image);
259 | cv::imshow(THRESH_WINDOW, threshold);
260 | }
261 |
262 |
263 | /* ==== OUTPUT TOPIC STREAMS ==== */
264 | cv_ptr->image = threshold;
265 | cv::waitKey(50);
266 |
267 | image_pub_.publish(cv_ptr->toImageMsg());
268 |
269 | }
270 | };
271 |
272 | int main(int argc, char** argv)
273 | {
274 |
275 | //z static float cam_x = 0; // dumb
276 |
277 | ros::init(argc, argv, "open_cv");
278 | ImageConverter ic;
279 | ros::spin();
280 | return 0;
281 | }
282 |
283 |
--------------------------------------------------------------------------------