├── .fig ├── cave.jpg ├── erding_airbase.jpg ├── forest.jpg ├── infinite_forest.jpg ├── logos.png ├── valley.jpg └── warehouse.jpg ├── .github └── workflows │ ├── ros_build_test.yml │ └── ros_package_build.yml ├── .gitignore ├── .gitman.yaml ├── CMakeLists.txt ├── LICENSE ├── README.md ├── cfg └── unreal_simulator.cfg ├── config ├── hw_api.yaml ├── uavs.yaml └── unreal_simulator.yaml ├── include ├── cereal ├── flight_forge_connector └── kissnet ├── launch ├── hw_api.launch ├── mapplan.launch ├── nodelet_manager.launch ├── stereo_image_proc.launch └── unreal_simulator.launch ├── nodelets.xml ├── package.xml ├── plugins.xml ├── scripts └── get_public_params.py ├── src ├── flight_forge_connector │ ├── flight_forge_connector.cpp │ ├── game_mode_controller.cpp │ └── socket_client.cpp ├── hw_api_plugin.cpp └── unreal_simulator.cpp ├── srv └── SetOrientation.srv └── tmux ├── one_drone ├── config │ ├── custom_config.yaml │ ├── network_config.yaml │ ├── octomap_planner.yaml │ ├── octomap_server.yaml │ ├── simulator.yaml │ └── world_config.yaml ├── kill.sh ├── layout.json ├── rviz.rviz ├── session.yml └── start.sh └── two_drones ├── config ├── custom_config.yaml ├── network_config.yaml ├── simulator.yaml └── world_config.yaml ├── kill.sh ├── layout.json ├── rviz.rviz ├── session.yml └── start.sh /.fig/cave.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctu-mrs/mrs_uav_unreal_simulation/7ff50eb9ff7b10c8bb36ebc1bedaa04a2c11c81d/.fig/cave.jpg -------------------------------------------------------------------------------- /.fig/erding_airbase.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctu-mrs/mrs_uav_unreal_simulation/7ff50eb9ff7b10c8bb36ebc1bedaa04a2c11c81d/.fig/erding_airbase.jpg -------------------------------------------------------------------------------- /.fig/forest.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctu-mrs/mrs_uav_unreal_simulation/7ff50eb9ff7b10c8bb36ebc1bedaa04a2c11c81d/.fig/forest.jpg -------------------------------------------------------------------------------- /.fig/infinite_forest.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctu-mrs/mrs_uav_unreal_simulation/7ff50eb9ff7b10c8bb36ebc1bedaa04a2c11c81d/.fig/infinite_forest.jpg -------------------------------------------------------------------------------- /.fig/logos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctu-mrs/mrs_uav_unreal_simulation/7ff50eb9ff7b10c8bb36ebc1bedaa04a2c11c81d/.fig/logos.png -------------------------------------------------------------------------------- /.fig/valley.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctu-mrs/mrs_uav_unreal_simulation/7ff50eb9ff7b10c8bb36ebc1bedaa04a2c11c81d/.fig/valley.jpg -------------------------------------------------------------------------------- /.fig/warehouse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctu-mrs/mrs_uav_unreal_simulation/7ff50eb9ff7b10c8bb36ebc1bedaa04a2c11c81d/.fig/warehouse.jpg -------------------------------------------------------------------------------- /.github/workflows/ros_build_test.yml: -------------------------------------------------------------------------------- 1 | name: ros_build_test 2 | 3 | on: 4 | 5 | push: 6 | branches: [ devel ] 7 | 8 | paths-ignore: 9 | - '**/README.md' 10 | 11 | pull_request: 12 | branches: [ master ] 13 | 14 | workflow_dispatch: 15 | 16 | concurrency: 17 | group: ${{ github.ref }} 18 | cancel-in-progress: true 19 | 20 | jobs: 21 | 22 | build: 23 | uses: ctu-mrs/ci_scripts/.github/workflows/ros_build_test.yml@master 24 | secrets: 25 | PUSH_TOKEN: ${{ secrets.PUSH_TOKEN }} 26 | -------------------------------------------------------------------------------- /.github/workflows/ros_package_build.yml: -------------------------------------------------------------------------------- 1 | name: ros_package_build 2 | 3 | on: 4 | 5 | push: 6 | branches: [ master ] 7 | 8 | paths-ignore: 9 | - '**/README.md' 10 | 11 | workflow_dispatch: 12 | 13 | concurrency: 14 | group: ${{ github.ref }} 15 | cancel-in-progress: true 16 | 17 | jobs: 18 | 19 | build: 20 | uses: ctu-mrs/ci_scripts/.github/workflows/ros_package_build.yml@master 21 | secrets: 22 | PUSH_TOKEN: ${{ secrets.PUSH_TOKEN }} 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.swo 3 | 4 | .vscode/ 5 | build/ 6 | 7 | .gitman/ -------------------------------------------------------------------------------- /.gitman.yaml: -------------------------------------------------------------------------------- 1 | location: .gitman 2 | sources: 3 | - repo: https://github.com/ctu-mrs/mrs_flight_forge_connector.git 4 | name: mrs_flight_forge_connector 5 | rev: master 6 | type: git 7 | params: 8 | sparse_paths: 9 | - src/ 10 | - include/ 11 | links: 12 | - 13 | scripts: 14 | - 15 | sources_locked: 16 | - repo: https://github.com/ctu-mrs/mrs_flight_forge_connector.git 17 | name: mrs_flight_forge_connector 18 | rev: 5f0dec855d185c7c9b815411d280ad61b8d90e82 19 | type: git 20 | params: 21 | sparse_paths: 22 | - src/ 23 | - include/ 24 | links: 25 | - 26 | scripts: 27 | - 28 | default_group: '' 29 | groups: 30 | - 31 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(mrs_uav_unreal_simulation) 3 | 4 | set(CMAKE_CXX_STANDARD 17) 5 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 6 | 7 | add_definitions(-Wall) 8 | add_definitions(-Wextra) 9 | 10 | set(CATKIN_DEPENDENCIES 11 | cmake_modules 12 | dynamic_reconfigure 13 | geometry_msgs 14 | mrs_lib 15 | mrs_msgs 16 | mrs_uav_hw_api 17 | nav_msgs 18 | nodelet 19 | roscpp 20 | rosgraph_msgs 21 | sensor_msgs 22 | std_msgs 23 | std_srvs 24 | mrs_multirotor_simulator 25 | message_generation 26 | message_runtime 27 | ) 28 | 29 | 30 | find_package(catkin REQUIRED COMPONENTS 31 | ${CATKIN_DEPENDENCIES} 32 | ) 33 | 34 | add_service_files(DIRECTORY srv/ FILES 35 | FILES 36 | SetOrientation.srv 37 | ) 38 | 39 | generate_messages( 40 | DEPENDENCIES 41 | geometry_msgs 42 | std_msgs 43 | ) 44 | 45 | generate_dynamic_reconfigure_options( 46 | cfg/unreal_simulator.cfg 47 | ) 48 | 49 | set(LIBRARIES 50 | MrsUavUnrealSimulation_Simulator 51 | MrsUavUnrealSimulation_HwApiPlugin 52 | MrsUavUnrealSimulation_UedsConnector 53 | ) 54 | 55 | catkin_package( 56 | LIBRARIES ${LIBRARIES} 57 | INCLUDE_DIRS include 58 | CATKIN_DEPENDS ${CATKIN_DEPENDENCIES} 59 | ) 60 | 61 | include_directories( 62 | include 63 | ${catkin_INCLUDE_DIRS} 64 | ${dynamic_reconfigure_PACKAGE_PATH}/cmake/cfgbuild.cmake 65 | ) 66 | 67 | 68 | ## | --------------------- UEDS connector --------------------- | 69 | 70 | add_library(MrsUavUnrealSimulation_UedsConnector 71 | src/flight_forge_connector/socket_client.cpp 72 | src/flight_forge_connector/flight_forge_connector.cpp 73 | src/flight_forge_connector/game_mode_controller.cpp 74 | ) 75 | 76 | ## | ------------------------ Simulator ----------------------- | 77 | 78 | add_library(MrsUavUnrealSimulation_Simulator 79 | src/unreal_simulator.cpp 80 | ) 81 | 82 | add_dependencies(MrsUavUnrealSimulation_Simulator 83 | ${${PROJECT_NAME}_EXPORTED_TARGETS} 84 | ${catkin_EXPORTED_TARGETS} 85 | ) 86 | 87 | target_link_libraries(MrsUavUnrealSimulation_Simulator 88 | MrsUavUnrealSimulation_UedsConnector 89 | ${LIB_UEDS_CONNECTOR} 90 | ${catkin_LIBRARIES} 91 | ${Eigen_LIBRARIES} 92 | ) 93 | 94 | ## | ---------------------- HW Api Plugin --------------------- | 95 | 96 | add_library(MrsUavUnrealSimulation_HwApiPlugin 97 | src/hw_api_plugin.cpp 98 | ) 99 | 100 | add_dependencies(MrsUavUnrealSimulation_HwApiPlugin 101 | ${${PROJECT_NAME}_EXPORTED_TARGETS} 102 | ${catkin_EXPORTED_TARGETS} 103 | ) 104 | 105 | target_link_libraries(MrsUavUnrealSimulation_HwApiPlugin 106 | ${catkin_LIBRARIES} 107 | ${Eigen_LIBRARIES} 108 | ) 109 | 110 | ## -------------------------------------------------------------- 111 | ## | Install | 112 | ## -------------------------------------------------------------- 113 | 114 | install(TARGETS ${LIBRARIES} 115 | ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 116 | LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 117 | RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} 118 | ) 119 | 120 | install(DIRECTORY launch config 121 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} 122 | ) 123 | 124 | install(DIRECTORY tmux/ 125 | USE_SOURCE_PERMISSIONS 126 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/tmux 127 | ) 128 | 129 | install(DIRECTORY scripts/ 130 | USE_SOURCE_PERMISSIONS 131 | DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} 132 | ) 133 | 134 | install(DIRECTORY scripts 135 | USE_SOURCE_PERMISSIONS 136 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} 137 | ) 138 | 139 | install(FILES nodelets.xml plugins.xml 140 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} 141 | ) 142 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MRS FlightForge Simulator 2 | ![logos](.fig/logos.png) 3 | 4 | 5 | ## Requirements 6 | 7 | * A dedicated NVidia GPU (at least MX450, RTX is recommended) or a comparable AMD GPU 8 | * 3 GB of HDD space 9 | 10 | ## The Maps 11 | 12 | | Map Name | | Map Name | | 13 | |-----------|-------------------------|----------------|-------------------------------| 14 | | Valley | ![](.fig/valley.jpg) | Cave | ![](.fig/cave.jpg) | 15 | | Forest | ![](.fig/forest.jpg) | Erding Airbase | ![](.fig/erding_airbase.jpg) | 16 | | Warehouse | ![](.fig/warehouse.jpg) | Infinite forest | ![](.fig/infinite_forest.jpg) | 17 | 18 | ## Controls 19 | 20 | * `m`/`ESC` - show menu for switching graphics and worlds 21 | 22 | ## Installation 23 | 24 | ### Linux 25 | 26 | 1. Install the [MRS UAV System](https://github.com/ctu-mrs/mrs_uav_system) 27 | 2. Install the MRS UAV System FlightForge endpoint 28 | ```bash 29 | sudo apt install ros-noetic-mrs-uav-unreal-simulation 30 | ``` 31 | 3. Download the and unpack [MRS FlightForge simulator](https://nasmrs.felk.cvut.cz/index.php/s/MnGARsSwnpeVy5z) 32 | 4. Launch the FlightForge Simulator by `./mrs_flight_forge.sh`. Alternatively, start it in a headless mode via `./mrs_flight_forge.sh -RenderOffscreen`. 33 | 6. Start the MRS UAV System FlightForge endpoint 34 | ```bash 35 | roscd mrs_uav_unreal_simulation 36 | ./tmux/one_drone/start.sh 37 | ``` 38 | 39 | ### Windows 40 | 41 | Requirements: 42 | * Windows 11 + updates 43 | * WSL 2.0 44 | 45 | 1. Install Ubuntu 20.04 into the WSL 2.0 using the Microsoft Store 46 | 2. Install the [MRS UAV System](https://github.com/ctu-mrs/mrs_uav_system) into WSL 2.0 47 | 3. Create `.wslconfig` file in `C:/Users//.wslconfig` 48 | 4. Place the following content into `.wslconfig` 49 | ``` 50 | [wsl2] 51 | firewall=false 52 | networkingMode=mirrored 53 | debugConsole=false 54 | [experimental] 55 | hostAddressLoopback=true 56 | ``` 57 | 5. Restart the WSL by issuing `wsl --shutdown` into a comand line. 58 | 6. Install the MRS UAV System FlightForge endpoint 59 | ```bash 60 | sudo apt install ros-noetic-mrs-uav-unreal-simulation 61 | ``` 62 | 7. Download and unpack the [FlightForge Simulator](https://nasmrs.felk.cvut.cz/index.php/s/MnGARsSwnpeVy5z) 63 | 8. Start the FlightForge Simulator 64 | 9. Start the MRS UAV System FlightForge endpoint 65 | ```bash 66 | roscd mrs_uav_unreal_simulation 67 | ./tmux/one_drone/start.sh 68 | ``` 69 | 10. The first start might require hitting "CTRL+C" in the `roscore` tab of the tmux session. The roscore is always stuck for the first time after rebooting the computer. 70 | 71 | ## Citing this work 72 | 73 | If you use this simulator in your research, please cite the following paper: 74 | 75 | ```@article{čapek2025flightforge, 76 | title = {FlightForge: Advancing UAV Research with Procedural Generation of High-Fidelity Simulation and Integrated Autonomy}, 77 | author = {David Čapek and Jan Hrnčíř and Tomáš Báča and Jakub Jirkal and Vojtěch Vonásek and Robert Pěnička and Martin Saska}, 78 | year = {2025}, 79 | journal = {arXiv preprint arXiv: 2502.05038}, 80 | url = {https://arxiv.org/abs/2502.05038v1}, 81 | pdf = {https://arxiv.org/pdf/2502.05038.pdf} 82 | } 83 | ``` 84 | 85 | ## Planned features 86 | 87 | * Adding back a grayscale normalized depth image 88 | * possible coloring of the depth pointcloud using the segmented RGB image 89 | -------------------------------------------------------------------------------- /cfg/unreal_simulator.cfg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | PACKAGE = "mrs_uav_unreal_simulation" 3 | 4 | import roslib; 5 | roslib.load_manifest(PACKAGE) 6 | 7 | from dynamic_reconfigure.parameter_generator_catkin import * 8 | 9 | gen = ParameterGenerator() 10 | 11 | simulation = gen.add_group("Simulation"); 12 | 13 | simulation.add("realtime_factor", double_t, 0, "Realtime factor", 0.0, 0.01, 10.0) 14 | simulation.add("dynamic_rtf", bool_t, 0, "Dynamic RTF", False) 15 | simulation.add("paused", bool_t, 0, "Paused", False) 16 | 17 | rangefinder = gen.add_group("Rangefinder") 18 | 19 | rangefinder.add("rangefinder_enabled", bool_t, 0, "Rangefinder enabled", True) 20 | rangefinder.add("rangefinder_rate", double_t, 0, "LiDAR rate", 1.0, 1.0, 200.0) 21 | 22 | lidar = gen.add_group("LiDAR"); 23 | 24 | lidar.add("lidar_enabled", bool_t, 0, "LiDAR enabled", True) 25 | lidar.add("lidar_rate", double_t, 0, "LiDAR rate", 1.0, 1.0, 200.0) 26 | lidar.add("lidar_noise_enabled", bool_t, 0, "LiDAR noise enabled", True) 27 | lidar.add("lidar_std_at_1m", double_t, 0, "LiDAR STD at 1m", 0.0, 0.01, 1.0) 28 | lidar.add("lidar_std_slope", double_t, 0, "LiDAR STD slope", 0.0, 0.01, 1.0) 29 | 30 | lidar_segmented = gen.add_group("Segmented LiDAR"); 31 | 32 | lidar_segmented.add("lidar_seg_enabled", bool_t, 0, "LiDAR segmented enabled", True) 33 | lidar_segmented.add("lidar_seg_rate", double_t, 0, "LiDAR segmented rate", 1.0, 1.0, 200.0) 34 | 35 | lidar_intensity = gen.add_group("Intensity LiDAR"); 36 | 37 | lidar_intensity.add("lidar_int_enabled", bool_t, 0, "LiDAR intensity enabled", True) 38 | lidar_intensity.add("lidar_int_rate", double_t, 0, "LiDAR intensity rate", 1.0, 1.0, 200.0) 39 | lidar_intensity.add("lidar_int_noise_enabled", bool_t, 0, "LiDAR intensity noise enabled", True) 40 | lidar_intensity.add("lidar_int_value_grass", double_t, 0, "LiDAR intensity value grass", 0.0, 0.0, 255.0) 41 | lidar_intensity.add("lidar_int_value_road", double_t, 0, "LiDAR intensity value road", 0.0, 0.0, 255.0) 42 | lidar_intensity.add("lidar_int_value_building", double_t, 0, "LiDAR intensity value building", 0.0, 0.0, 255.0) 43 | lidar_intensity.add("lidar_int_value_tree", double_t, 0, "LiDAR intensity value tree", 0.0, 0.0, 255.0) 44 | lidar_intensity.add("lidar_int_value_fence", double_t, 0, "LiDAR intensity value fence", 0.0, 0.0, 255.0) 45 | lidar_intensity.add("lidar_int_value_dirt_road", double_t, 0, "LiDAR intensity value dirt road", 0.0, 0.0, 255.0) 46 | lidar_intensity.add("lidar_int_value_other", double_t, 0, "LiDAR intensity value other", 0.0, 0.0, 255.0) 47 | lidar_intensity.add("lidar_int_std_at_1m", double_t, 0, "LiDAR intensity STD at 1m", 0.0, 0.01, 1.0) 48 | lidar_intensity.add("lidar_int_std_slope", double_t, 0, "LiDAR intensity STD slope", 0.0, 0.01, 1.0) 49 | rgb = gen.add_group("RGB"); 50 | 51 | rgb.add("rgb_enabled", bool_t, 0, "RGB enabled", False) 52 | rgb.add("rgb_rate", double_t, 0, "RGB rate", 1.0, 1.0, 200.0) 53 | 54 | rgb_segmented = gen.add_group("Segmented RGB"); 55 | 56 | rgb_segmented.add("rgb_segmented_enabled", bool_t, 0, "RGB segmented enabled", True) 57 | rgb_segmented.add("rgb_segmented_rate", double_t, 0, "RGB segmented rate", 1.0, 1.0, 200.0) 58 | 59 | stereo = gen.add_group("Stereo"); 60 | 61 | stereo.add("stereo_enabled", bool_t, 0, "stereo enabled", False) 62 | stereo.add("stereo_rate", double_t, 0, "stereo rate", 1.0, 1.0, 200.0) 63 | 64 | exit(gen.generate(PACKAGE, "UnrealSimulator", "unreal_simulator")) 65 | -------------------------------------------------------------------------------- /config/hw_api.yaml: -------------------------------------------------------------------------------- 1 | hw_interface_plugin: "mrs_uav_unreal_simulation/Api" 2 | 3 | gnss: 4 | utm_zone: "32U" 5 | utm_x: 717652.458 6 | utm_y: 5355604.146 7 | amsl: 460.0 8 | 9 | input_mode: 10 | actuators: false 11 | control_group: false 12 | attitude_rate: true 13 | attitude: true 14 | acceleration_hdg_rate: false 15 | acceleration_hdg: false 16 | velocity_hdg_rate: false 17 | velocity_hdg: false 18 | position: false 19 | 20 | feedforward: true 21 | 22 | outputs: 23 | gnss: true 24 | rtk: true 25 | imu: true 26 | altitude: true 27 | magnetometer_heading: true 28 | rc_channels: true 29 | battery_state: true 30 | position: true 31 | orientation: true 32 | velocity: true 33 | angular_velocity: true 34 | odometry: true 35 | ground_truth: true 36 | -------------------------------------------------------------------------------- /config/uavs.yaml: -------------------------------------------------------------------------------- 1 | uav_names: [ 2 | "uav1", 3 | ] 4 | 5 | uav1: 6 | type: "x500" 7 | spawn: 8 | x: 0.0 9 | y: 0.0 10 | z: 0.0 11 | heading: 0.0 12 | -------------------------------------------------------------------------------- /config/unreal_simulator.yaml: -------------------------------------------------------------------------------- 1 | simulation_rate: 250.0 # Hz 2 | clock_rate: 250.0 # Hz 3 | 4 | # desired realtime factor 5 | realtime_factor: 1.0 # [-] 6 | 7 | # if true, the RTF is automatically set such that the fastest sensor is always rendered at the desired rate 8 | dynamic_rtf: true 9 | 10 | # TODO describe 11 | collisions: true 12 | 13 | # Set mutual visibilitiy and collision of UAVs 14 | uavs_mutual_visibility: true 15 | 16 | # 0 - LOW 17 | # 1 - MEDIUM 18 | # 2 - HIGH 19 | # 4 - EPIC 20 | # 5 - CINEMATIC 21 | graphics_settings: "medium" 22 | 23 | # 0 - VALLEY 24 | # 1 - FOREST 25 | # 2 - INFINITE_FOREST 26 | # 3 - WAREHOUSE 27 | # 4 - CAVE 28 | # 5 - ERDING_AIRBASE 29 | # 6 - TEMESVAR :D 30 | world_name: "infinite_forest" 31 | 32 | # {"sunny", 0}, 33 | # {"cloudy", 1}, 34 | # {"foggy", 2}, 35 | # {"rain", 3}, 36 | # {"rain_light", 4}, 37 | # {"rain_thunderstorm", 5}, 38 | # {"sand_dust_calm", 6}, 39 | # {"sand_dust_storm", 7}, 40 | # {"snow", 8}, 41 | # {"snow_blizzards", 9} 42 | weather_type: "foggy" 43 | 44 | daytime: 45 | hour: 7 46 | minute: 30 47 | 48 | ############ Only Forest Procedural Generation settings ############ 49 | 50 | # Choose cluttered difficulties from 1 [high] to 10 [low] 51 | ueds_forest_density: 6 52 | 53 | # Choose Hilly Level from 1 [totally flat] to 5 [the most hilly] 54 | ueds_forest_hilly_level: 3 55 | 56 | #################################################################### 57 | 58 | sensors: 59 | 60 | rangefinder: 61 | 62 | enabled: true 63 | rate: 10.0 # [Hz] 64 | 65 | lidar: 66 | 67 | enabled: false 68 | livox: false 69 | 70 | rate: 10.0 # [Hz] 71 | 72 | horizontal_fov_left: 180.0 # [deg] 73 | horizontal_fov_right: 180.0 # [deg] 74 | 75 | vertical_fov_up: 52.0 # [deg] 76 | vertical_fov_down: 7.0 # [deg] 77 | 78 | 79 | horizontal_rays: 128 # [-] 80 | vertical_rays: 64 # [-] 81 | 82 | offset_x: 0.0 # [m] 83 | offset_y: 0.0 # [m] 84 | offset_z: 0.06 # [m] 85 | 86 | # TODO which Tait-Bryan convention is it in? 87 | rotation_pitch: 0.0 # [deg] 88 | rotation_roll: 0.0 # [deg] 89 | rotation_yaw: 0.0 # [deg] 90 | 91 | beam_length: 20.0 # [m] 92 | 93 | noise: 94 | 95 | enabled: true 96 | 97 | std_at_1m: 0.01 # [m] 98 | std_slope: 0.2 # [-] # multiplies std_at_1m for each meter of measured distances 99 | 100 | show_beams: false # TODO broken 101 | 102 | lidar_segmented: 103 | enabled: false 104 | rate: 10.0 # [Hz] 105 | 106 | lidar_intensity: 107 | enabled: false 108 | rate: 10.0 # [Hz] 109 | 110 | values: 111 | grass: 50 112 | road: 7 113 | tree: 90 114 | building: 70 115 | fence: 40 116 | dirt_road: 30 117 | other: 155 118 | 119 | noise: 120 | enabled: true 121 | std_at_1m: 0.59 # [-] 122 | std_slope: 0.81 # [-] # multiplies std_at_1m for each meter of measured distances 123 | 124 | 125 | rgb: 126 | enabled: false 127 | 128 | rate: 30.0 # [Hz] 129 | 130 | enable_hdr: true 131 | enable_temporal_aa: true 132 | enable_raytracing: true 133 | 134 | width: 640 # [px] 135 | height: 480 # [px] 136 | fov: 120.0 # [deg] 137 | 138 | offset_x: 0.14 # [m] 139 | offset_y: 0.0 # [m] 140 | offset_z: 0.0 # [m] 141 | 142 | # TODO which Tait-Bryan convention is it in? 143 | rotation_pitch: 0.0 # [deg] 144 | rotation_yaw: 0.0 # [deg] 145 | rotation_roll: 0.0 # [deg] 146 | 147 | enable_motion_blur: true 148 | motion_blur_amount: 0.5 # [0.0 - 1.0] 149 | motion_blur_distortion: 50.0 # [0-100] 150 | 151 | rgb_segmented: 152 | enabled: false 153 | rate: 5.0 # [Hz] 154 | 155 | stereo: 156 | 157 | enabled: false 158 | 159 | rate: 10.0 # [Hz] 160 | 161 | enable_hdr: true 162 | enable_temporal_aa: true 163 | enable_raytracing: true 164 | 165 | baseline: 0.1 # [m] 166 | 167 | width: 640 # [px] 168 | height: 480 # [px] 169 | fov: 90.0 # [deg] 170 | 171 | offset_x: 0.14 # [m] 172 | offset_y: 0.0 # [m] 173 | offset_z: 0.0 # [m] 174 | 175 | # TODO which Tait-Bryan convention is it in? 176 | rotation_pitch: 20.0 # [deg] 177 | rotation_yaw: 0.0 # [deg] 178 | rotation_roll: 0.0 # [deg] 179 | 180 | frames: 181 | world: 182 | name: "simulator_origin" 183 | prefix_with_uav_name: false 184 | fcu: 185 | name: "fcu" 186 | publish_tf: false 187 | rangefinder: 188 | name: "garmin" 189 | publish_tf: false 190 | 191 | # randomization of the initial conditions around the desired spawn point 192 | randomization: 193 | 194 | enabled: false 195 | 196 | bounds: 197 | x: 15.0 # [m] 198 | y: 15.0 # [m] 199 | z: 15.0 # [m] 200 | 201 | # this virtual ground is simulated outside of Unreal, therefore should be turned off 202 | ground: 203 | enabled: false 204 | z: 0.0 # [m] 205 | 206 | input_timeout: 1.0 # [s] 207 | 208 | iterate_without_input: true 209 | 210 | g: 9.81 # [ms^-2] 211 | 212 | # * when enabled, this will place a temporary patch of ground just under the spawn location 213 | # * this patch will disappear after the total_thrust > 0.9*hover_thrust 214 | individual_takeoff_platform: 215 | enabled: true 216 | -------------------------------------------------------------------------------- /include/cereal: -------------------------------------------------------------------------------- 1 | ../.gitman/mrs_flight_forge_connector/include/cereal -------------------------------------------------------------------------------- /include/flight_forge_connector: -------------------------------------------------------------------------------- 1 | ../.gitman/mrs_flight_forge_connector/include/flight_forge_connector -------------------------------------------------------------------------------- /include/kissnet: -------------------------------------------------------------------------------- 1 | ../.gitman/mrs_flight_forge_connector/include/kissnet -------------------------------------------------------------------------------- /launch/hw_api.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 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 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /launch/mapplan.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 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 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /launch/nodelet_manager.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /launch/stereo_image_proc.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /launch/unreal_simulator.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 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 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /nodelets.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | UnrealSimulator nodelet 4 | 5 | 6 | -------------------------------------------------------------------------------- /package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | mrs_uav_unreal_simulation 5 | 1.0.1 6 | The MRS UnrealEngine simulator 7 | 8 | Tomas Baca 9 | Tomas Baca 10 | 11 | BSD 3-Clause 12 | 13 | catkin 14 | 15 | cmake_modules 16 | dynamic_reconfigure 17 | geometry_msgs 18 | mrs_lib 19 | mrs_msgs 20 | mrs_uav_hw_api 21 | nav_msgs 22 | nodelet 23 | roscpp 24 | rosgraph_msgs 25 | sensor_msgs 26 | std_msgs 27 | std_srvs 28 | mrs_multirotor_simulator 29 | stereo_image_proc 30 | message_generation 31 | message_runtime 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /plugins.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | MRS UAV Unreal simulator API plugin for the MRS UAV System 4 | 5 | 6 | -------------------------------------------------------------------------------- /scripts/get_public_params.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import rospkg 4 | import os 5 | 6 | class ParamsGetter: 7 | 8 | def __init__(self): 9 | 10 | package_name = "mrs_multirotor_simulator" 11 | 12 | rospack = rospkg.RosPack() 13 | 14 | package_path = rospack.get_path(package_name) 15 | 16 | file_paths = [] 17 | 18 | for path, subdirs, files in os.walk(package_path + "/config/"): 19 | for name in files: 20 | if name.endswith(".yaml") or name.endswith(".yml"): 21 | file_paths.append(os.path.join(path, name)) 22 | 23 | for file_path in file_paths: 24 | 25 | if os.path.getsize(file_path) == 0: 26 | continue 27 | 28 | with open(file_path, 'r') as file: 29 | try: 30 | contents = file.read() 31 | print("######################################") 32 | print("# The following section was take from:") 33 | print("# {}".format(file_path)) 34 | print("") 35 | print(contents) 36 | except: 37 | print("There was a problem while opening the file '{}'".format(file_path)) 38 | break 39 | 40 | if __name__ == '__main__': 41 | params_getter = ParamsGetter() 42 | -------------------------------------------------------------------------------- /src/flight_forge_connector/flight_forge_connector.cpp: -------------------------------------------------------------------------------- 1 | ../../.gitman/mrs_flight_forge_connector/src/flight_forge_connector.cpp -------------------------------------------------------------------------------- /src/flight_forge_connector/game_mode_controller.cpp: -------------------------------------------------------------------------------- 1 | ../../.gitman/mrs_flight_forge_connector/src/game_mode_controller.cpp -------------------------------------------------------------------------------- /src/flight_forge_connector/socket_client.cpp: -------------------------------------------------------------------------------- 1 | ../../.gitman/mrs_flight_forge_connector/src/socket_client.cpp -------------------------------------------------------------------------------- /src/hw_api_plugin.cpp: -------------------------------------------------------------------------------- 1 | /* includes //{ */ 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | //} 22 | 23 | namespace mrs_uav_unreal_simulation 24 | { 25 | 26 | /* class Api //{ */ 27 | 28 | class Api : public mrs_uav_hw_api::MrsUavHwApi { 29 | 30 | public: 31 | ~Api(){}; 32 | 33 | void initialize(const ros::NodeHandle& parent_nh, std::shared_ptr common_handlers); 34 | 35 | // | ------------------------- params ------------------------- | 36 | 37 | mrs_msgs::HwApiCapabilities _capabilities_; 38 | 39 | bool _feedforward_enabled_; 40 | 41 | double _utm_x_; 42 | double _utm_y_; 43 | std::string _utm_zone_; 44 | double _amsl_; 45 | 46 | std::string _uav_name_; 47 | std::string _world_frame_name_; 48 | std::string _body_frame_name_; 49 | 50 | // | --------------------- status methods --------------------- | 51 | 52 | mrs_msgs::HwApiStatus getStatus(); 53 | mrs_msgs::HwApiCapabilities getCapabilities(); 54 | 55 | // | --------------------- topic callbacks -------------------- | 56 | 57 | bool callbackActuatorCmd(const mrs_msgs::HwApiActuatorCmd::ConstPtr msg); 58 | bool callbackControlGroupCmd(const mrs_msgs::HwApiControlGroupCmd::ConstPtr msg); 59 | bool callbackAttitudeRateCmd(const mrs_msgs::HwApiAttitudeRateCmd::ConstPtr msg); 60 | bool callbackAttitudeCmd(const mrs_msgs::HwApiAttitudeCmd::ConstPtr msg); 61 | bool callbackAccelerationHdgRateCmd(const mrs_msgs::HwApiAccelerationHdgRateCmd::ConstPtr msg); 62 | bool callbackAccelerationHdgCmd(const mrs_msgs::HwApiAccelerationHdgCmd::ConstPtr msg); 63 | bool callbackVelocityHdgRateCmd(const mrs_msgs::HwApiVelocityHdgRateCmd::ConstPtr msg); 64 | bool callbackVelocityHdgCmd(const mrs_msgs::HwApiVelocityHdgCmd::ConstPtr msg); 65 | bool callbackPositionCmd(const mrs_msgs::HwApiPositionCmd::ConstPtr msg); 66 | 67 | void callbackTrackerCmd(const mrs_msgs::TrackerCommand::ConstPtr msg); 68 | 69 | // | -------------------- service callbacks ------------------- | 70 | 71 | std::tuple callbackArming(const bool& request); 72 | std::tuple callbackOffboard(void); 73 | 74 | private: 75 | bool is_initialized_ = false; 76 | 77 | std::shared_ptr common_handlers_; 78 | 79 | // | ----------------------- subscribers ---------------------- | 80 | 81 | mrs_lib::SubscribeHandler sh_odom_; 82 | mrs_lib::SubscribeHandler sh_imu_; 83 | mrs_lib::SubscribeHandler sh_range_; 84 | 85 | void callbackOdom(const nav_msgs::Odometry::ConstPtr msg); 86 | void callbackImu(const sensor_msgs::Imu::ConstPtr msg); 87 | 88 | // | ----------------------- publishers ----------------------- | 89 | 90 | mrs_lib::PublisherHandler ph_actuators_cmd_; 91 | mrs_lib::PublisherHandler ph_control_group_cmd_; 92 | mrs_lib::PublisherHandler ph_attitude_rate_cmd_; 93 | mrs_lib::PublisherHandler ph_attitude_cmd_; 94 | mrs_lib::PublisherHandler ph_acceleration_hdg_rate_cmd_; 95 | mrs_lib::PublisherHandler ph_acceleration_hdg_cmd_; 96 | mrs_lib::PublisherHandler ph_velocity_hdg_rate_cmd_; 97 | mrs_lib::PublisherHandler ph_velocity_hdg_cmd_; 98 | mrs_lib::PublisherHandler ph_position_cmd_; 99 | mrs_lib::PublisherHandler ph_tracker_cmd_; 100 | 101 | // | ------------------------- timers ------------------------- | 102 | 103 | ros::Timer timer_main_; 104 | 105 | void timerMain(const ros::TimerEvent& event); 106 | 107 | // | ------------------------ variables ----------------------- | 108 | 109 | std::atomic offboard_ = false; 110 | std::string mode_; 111 | std::atomic armed_ = false; 112 | std::atomic connected_ = false; 113 | std::mutex mutex_status_; 114 | 115 | // | ------------------------- methods ------------------------ | 116 | 117 | void publishBatteryState(void); 118 | 119 | void publishRC(void); 120 | 121 | void timeoutInputs(void); 122 | }; 123 | 124 | //} 125 | 126 | // -------------------------------------------------------------- 127 | // | controller's interface | 128 | // -------------------------------------------------------------- 129 | 130 | /* initialize() //{ */ 131 | 132 | void Api::initialize(const ros::NodeHandle& parent_nh, std::shared_ptr common_handlers) { 133 | 134 | ros::NodeHandle nh_(parent_nh); 135 | 136 | common_handlers_ = common_handlers; 137 | 138 | _capabilities_.api_name = "MrsSimulator"; 139 | 140 | _uav_name_ = common_handlers->getUavName(); 141 | _body_frame_name_ = common_handlers->getBodyFrameName(); 142 | _world_frame_name_ = common_handlers->getWorldFrameName(); 143 | 144 | // | ------------------- loading parameters ------------------- | 145 | 146 | mrs_lib::ParamLoader param_loader(nh_, "MrsUavHwApi"); 147 | 148 | param_loader.loadParam("gnss/utm_x", _utm_x_); 149 | param_loader.loadParam("gnss/utm_y", _utm_y_); 150 | param_loader.loadParam("gnss/utm_zone", _utm_zone_); 151 | param_loader.loadParam("gnss/amsl", _amsl_); 152 | 153 | param_loader.loadParam("input_mode/actuators", (bool&)_capabilities_.accepts_actuator_cmd); 154 | param_loader.loadParam("input_mode/control_group", (bool&)_capabilities_.accepts_control_group_cmd); 155 | param_loader.loadParam("input_mode/attitude_rate", (bool&)_capabilities_.accepts_attitude_rate_cmd); 156 | param_loader.loadParam("input_mode/attitude", (bool&)_capabilities_.accepts_attitude_cmd); 157 | param_loader.loadParam("input_mode/acceleration_hdg_rate", (bool&)_capabilities_.accepts_acceleration_hdg_rate_cmd); 158 | param_loader.loadParam("input_mode/acceleration_hdg", (bool&)_capabilities_.accepts_acceleration_hdg_cmd); 159 | param_loader.loadParam("input_mode/velocity_hdg_rate", (bool&)_capabilities_.accepts_velocity_hdg_rate_cmd); 160 | param_loader.loadParam("input_mode/velocity_hdg", (bool&)_capabilities_.accepts_velocity_hdg_cmd); 161 | param_loader.loadParam("input_mode/position", (bool&)_capabilities_.accepts_position_cmd); 162 | param_loader.loadParam("input_mode/feedforward", _feedforward_enabled_); 163 | 164 | param_loader.loadParam("outputs/gnss", (bool&)_capabilities_.produces_gnss); 165 | param_loader.loadParam("outputs/rtk", (bool&)_capabilities_.produces_rtk); 166 | param_loader.loadParam("outputs/imu", (bool&)_capabilities_.produces_imu); 167 | param_loader.loadParam("outputs/altitude", (bool&)_capabilities_.produces_altitude); 168 | param_loader.loadParam("outputs/magnetometer_heading", (bool&)_capabilities_.produces_magnetometer_heading); 169 | param_loader.loadParam("outputs/rc_channels", (bool&)_capabilities_.produces_rc_channels); 170 | param_loader.loadParam("outputs/battery_state", (bool&)_capabilities_.produces_battery_state); 171 | param_loader.loadParam("outputs/position", (bool&)_capabilities_.produces_position); 172 | param_loader.loadParam("outputs/orientation", (bool&)_capabilities_.produces_orientation); 173 | param_loader.loadParam("outputs/velocity", (bool&)_capabilities_.produces_velocity); 174 | param_loader.loadParam("outputs/angular_velocity", (bool&)_capabilities_.produces_angular_velocity); 175 | param_loader.loadParam("outputs/odometry", (bool&)_capabilities_.produces_odometry); 176 | param_loader.loadParam("outputs/ground_truth", (bool&)_capabilities_.produces_ground_truth); 177 | 178 | _capabilities_.produces_magnetic_field = false; 179 | 180 | if (!param_loader.loadedSuccessfully()) { 181 | ROS_ERROR("[MrsUavHwDummyApi]: Could not load all parameters!"); 182 | ros::shutdown(); 183 | } 184 | 185 | // | ----------------------- subscribers ---------------------- | 186 | 187 | mrs_lib::SubscribeHandlerOptions shopts; 188 | shopts.nh = nh_; 189 | shopts.node_name = "MrsSimulatorHwApi"; 190 | shopts.no_message_timeout = mrs_lib::no_timeout; 191 | shopts.threadsafe = true; 192 | shopts.autostart = true; 193 | shopts.queue_size = 10; 194 | shopts.transport_hints = ros::TransportHints().tcpNoDelay(); 195 | 196 | sh_odom_ = mrs_lib::SubscribeHandler(shopts, "simulator_odom_in", &Api::callbackOdom, this); 197 | 198 | sh_imu_ = mrs_lib::SubscribeHandler(shopts, "simulator_imu_in", &Api::callbackImu, this); 199 | 200 | // | ----------------------- publishers ----------------------- | 201 | 202 | if (_capabilities_.accepts_actuator_cmd) { 203 | ph_actuators_cmd_ = mrs_lib::PublisherHandler(nh_, "simulator_actuators_cmd_out", 1); 204 | } 205 | 206 | if (_capabilities_.accepts_control_group_cmd) { 207 | ph_control_group_cmd_ = mrs_lib::PublisherHandler(nh_, "simulator_control_group_cmd_out", 1); 208 | } 209 | 210 | if (_capabilities_.accepts_attitude_rate_cmd) { 211 | ph_attitude_rate_cmd_ = mrs_lib::PublisherHandler(nh_, "simulator_attitude_rate_cmd_out", 1); 212 | } 213 | 214 | if (_capabilities_.accepts_attitude_cmd) { 215 | ph_attitude_cmd_ = mrs_lib::PublisherHandler(nh_, "simulator_attitude_cmd_out", 1); 216 | } 217 | 218 | if (_capabilities_.accepts_acceleration_hdg_rate_cmd) { 219 | ph_acceleration_hdg_rate_cmd_ = mrs_lib::PublisherHandler(nh_, "simulator_acceleration_hdg_rate_cmd_out", 1); 220 | } 221 | 222 | if (_capabilities_.accepts_acceleration_hdg_cmd) { 223 | ph_acceleration_hdg_cmd_ = mrs_lib::PublisherHandler(nh_, "simulator_acceleration_hdg_cmd_out", 1); 224 | } 225 | 226 | if (_capabilities_.accepts_velocity_hdg_rate_cmd) { 227 | ph_velocity_hdg_rate_cmd_ = mrs_lib::PublisherHandler(nh_, "simulator_velocity_hdg_rate_cmd_out", 1); 228 | } 229 | 230 | if (_capabilities_.accepts_velocity_hdg_cmd) { 231 | ph_velocity_hdg_cmd_ = mrs_lib::PublisherHandler(nh_, "simulator_velocity_hdg_cmd_out", 1); 232 | } 233 | 234 | if (_capabilities_.accepts_position_cmd) { 235 | ph_position_cmd_ = mrs_lib::PublisherHandler(nh_, "simulator_position_cmd_out", 1); 236 | } 237 | 238 | if (_feedforward_enabled_) { 239 | ph_tracker_cmd_ = mrs_lib::PublisherHandler(nh_, "simulator_tracker_cmd_out", 1); 240 | } 241 | 242 | // | ------------------------- timers ------------------------- | 243 | 244 | timer_main_ = nh_.createTimer(ros::Rate(10.0), &Api::timerMain, this); 245 | 246 | // | ----------------------- finish init ---------------------- | 247 | 248 | ROS_INFO("[MrsUavHwDummyApi]: initialized"); 249 | 250 | is_initialized_ = true; 251 | } 252 | 253 | //} 254 | 255 | /* getStatus() //{ */ 256 | 257 | mrs_msgs::HwApiStatus Api::getStatus() { 258 | 259 | mrs_msgs::HwApiStatus status; 260 | 261 | status.stamp = ros::Time::now(); 262 | 263 | bool has_odom = sh_odom_.hasMsg(); 264 | 265 | { 266 | std::scoped_lock lock(mutex_status_); 267 | 268 | status.armed = armed_; 269 | status.offboard = offboard_; 270 | status.connected = has_odom; 271 | status.mode = mode_; 272 | } 273 | 274 | return status; 275 | } 276 | 277 | //} 278 | 279 | /* getCapabilities() //{ */ 280 | 281 | mrs_msgs::HwApiCapabilities Api::getCapabilities() { 282 | 283 | _capabilities_.stamp = ros::Time::now(); 284 | 285 | return _capabilities_; 286 | } 287 | 288 | //} 289 | 290 | /* callbackArming() //{ */ 291 | 292 | std::tuple Api::callbackArming([[maybe_unused]] const bool& request) { 293 | 294 | std::stringstream ss; 295 | 296 | if (request) { 297 | 298 | armed_ = true; 299 | 300 | ss << "armed"; 301 | ROS_INFO_STREAM_THROTTLE(1.0, "[MrsSimulatorHwApi]: " << ss.str()); 302 | return std::tuple(true, ss.str()); 303 | 304 | } else { 305 | 306 | armed_ = false; 307 | 308 | ss << "disarmed"; 309 | ROS_INFO_STREAM_THROTTLE(1.0, "[MrsSimulatorHwApi]: " << ss.str()); 310 | return std::tuple(true, ss.str()); 311 | } 312 | } 313 | 314 | //} 315 | 316 | /* callbackOffboard() //{ */ 317 | 318 | std::tuple Api::callbackOffboard(void) { 319 | 320 | std::stringstream ss; 321 | 322 | if (!armed_) { 323 | ss << "Cannot switch to offboard, not armed."; 324 | ROS_INFO_THROTTLE(1.0, "[MrsSimulatorHwApi]: %s", ss.str().c_str()); 325 | return {false, ss.str()}; 326 | } 327 | 328 | offboard_ = true; 329 | 330 | ss << "Offboard set"; 331 | ROS_INFO_THROTTLE(1.0, "[MrsSimulatorHwApi]: %s", ss.str().c_str()); 332 | return {true, ss.str()}; 333 | } 334 | 335 | //} 336 | 337 | // | --------------------- input callbacks -------------------- | 338 | 339 | /* callbackActuatorCmd() //{ */ 340 | 341 | bool Api::callbackActuatorCmd(const mrs_msgs::HwApiActuatorCmd::ConstPtr msg) { 342 | 343 | if (!_capabilities_.accepts_actuator_cmd) { 344 | return false; 345 | } 346 | 347 | ROS_INFO_ONCE("[Api]: getting actuators cmd"); 348 | 349 | ph_actuators_cmd_.publish(msg); 350 | 351 | return true; 352 | } 353 | 354 | //} 355 | 356 | /* callbackControlGroupCmd() //{ */ 357 | 358 | bool Api::callbackControlGroupCmd(const mrs_msgs::HwApiControlGroupCmd::ConstPtr msg) { 359 | 360 | if (!_capabilities_.accepts_control_group_cmd) { 361 | return false; 362 | } 363 | 364 | ROS_INFO_ONCE("[Api]: getting control group cmd"); 365 | 366 | ph_control_group_cmd_.publish(msg); 367 | 368 | return true; 369 | } 370 | 371 | //} 372 | 373 | /* callbackAttitudeRateCmd() //{ */ 374 | 375 | bool Api::callbackAttitudeRateCmd(const mrs_msgs::HwApiAttitudeRateCmd::ConstPtr msg) { 376 | 377 | if (!_capabilities_.accepts_attitude_rate_cmd) { 378 | return false; 379 | } 380 | 381 | ROS_INFO_ONCE("[Api]: getting attitude rate cmd"); 382 | 383 | ph_attitude_rate_cmd_.publish(msg); 384 | 385 | return true; 386 | } 387 | 388 | //} 389 | 390 | /* callbackAttitudeCmd() //{ */ 391 | 392 | bool Api::callbackAttitudeCmd(const mrs_msgs::HwApiAttitudeCmd::ConstPtr msg) { 393 | 394 | if (!_capabilities_.accepts_attitude_cmd) { 395 | return false; 396 | } 397 | 398 | ROS_INFO_ONCE("[Api]: getting attitude cmd"); 399 | 400 | ph_attitude_cmd_.publish(msg); 401 | 402 | return true; 403 | } 404 | 405 | //} 406 | 407 | /* callbackAccelerationHdgRateCmd() //{ */ 408 | 409 | bool Api::callbackAccelerationHdgRateCmd(const mrs_msgs::HwApiAccelerationHdgRateCmd::ConstPtr msg) { 410 | 411 | if (!_capabilities_.accepts_acceleration_hdg_rate_cmd) { 412 | return false; 413 | } 414 | 415 | ROS_INFO_ONCE("[Api]: getting acceleration+hdg rate cmd"); 416 | 417 | ph_acceleration_hdg_rate_cmd_.publish(msg); 418 | 419 | return true; 420 | } 421 | 422 | //} 423 | 424 | /* callbackAccelerationHdgCmd() //{ */ 425 | 426 | bool Api::callbackAccelerationHdgCmd(const mrs_msgs::HwApiAccelerationHdgCmd::ConstPtr msg) { 427 | 428 | if (!_capabilities_.accepts_acceleration_hdg_cmd) { 429 | 430 | return false; 431 | } 432 | 433 | ROS_INFO_ONCE("[Api]: getting acceleration+hdg cmd"); 434 | 435 | ph_acceleration_hdg_cmd_.publish(msg); 436 | 437 | return true; 438 | } 439 | 440 | //} 441 | 442 | /* callbackVelocityHdgRateCmd() //{ */ 443 | 444 | bool Api::callbackVelocityHdgRateCmd(const mrs_msgs::HwApiVelocityHdgRateCmd::ConstPtr msg) { 445 | 446 | if (!_capabilities_.accepts_velocity_hdg_rate_cmd) { 447 | return false; 448 | } 449 | 450 | ROS_INFO_ONCE("[Api]: getting velocity+hdg rate cmd"); 451 | 452 | ph_velocity_hdg_rate_cmd_.publish(msg); 453 | 454 | return true; 455 | } 456 | 457 | //} 458 | 459 | /* callbackVelocityHdgCmd() //{ */ 460 | 461 | bool Api::callbackVelocityHdgCmd(const mrs_msgs::HwApiVelocityHdgCmd::ConstPtr msg) { 462 | 463 | if (!_capabilities_.accepts_velocity_hdg_cmd) { 464 | return false; 465 | } 466 | 467 | ROS_INFO_ONCE("[Api]: getting velocity+hdg cmd"); 468 | 469 | ph_velocity_hdg_cmd_.publish(msg); 470 | 471 | return true; 472 | } 473 | 474 | //} 475 | 476 | /* callbackPositionCmd() //{ */ 477 | 478 | bool Api::callbackPositionCmd(const mrs_msgs::HwApiPositionCmd::ConstPtr msg) { 479 | 480 | if (!_capabilities_.accepts_position_cmd) { 481 | return false; 482 | } 483 | 484 | ROS_INFO_ONCE("[Api]: getting position cmd"); 485 | 486 | ph_position_cmd_.publish(msg); 487 | 488 | return true; 489 | } 490 | 491 | //} 492 | 493 | /* callbackTrackerCmd() //{ */ 494 | 495 | void Api::callbackTrackerCmd(const mrs_msgs::TrackerCommand::ConstPtr msg) { 496 | 497 | ROS_INFO_ONCE("[Api]: getting tracker cmd"); 498 | 499 | ph_tracker_cmd_.publish(msg); 500 | } 501 | 502 | //} 503 | 504 | // | ------------------------ callbacks ----------------------- | 505 | 506 | /* //{ callbackOdom() */ 507 | 508 | void Api::callbackOdom(const nav_msgs::Odometry::ConstPtr msg) { 509 | 510 | if (!is_initialized_) { 511 | return; 512 | } 513 | 514 | ROS_INFO_ONCE("[Api]: getting simulator odometry"); 515 | 516 | auto odom = msg; 517 | 518 | { 519 | std::scoped_lock lock(mutex_status_); 520 | 521 | connected_ = true; 522 | } 523 | 524 | // | ----------------- publish the diagnostics ---------------- | 525 | 526 | mrs_msgs::HwApiStatus status; 527 | 528 | { 529 | std::scoped_lock lock(mutex_status_); 530 | 531 | status.stamp = ros::Time::now(); 532 | status.armed = armed_; 533 | status.offboard = offboard_; 534 | status.connected = connected_; 535 | status.mode = mode_; 536 | } 537 | 538 | common_handlers_->publishers.publishStatus(status); 539 | 540 | // | -------------------- publish position -------------------- | 541 | 542 | if (_capabilities_.produces_position) { 543 | 544 | geometry_msgs::PointStamped position; 545 | 546 | position.header.stamp = odom->header.stamp; 547 | position.header.frame_id = _uav_name_ + "/" + _world_frame_name_; 548 | position.point = odom->pose.pose.position; 549 | 550 | common_handlers_->publishers.publishPosition(position); 551 | } 552 | 553 | // | ------------------- publish orientation ------------------ | 554 | 555 | if (_capabilities_.produces_orientation) { 556 | 557 | geometry_msgs::QuaternionStamped orientation; 558 | 559 | orientation.header.stamp = odom->header.stamp; 560 | orientation.header.frame_id = _uav_name_ + "/" + _world_frame_name_; 561 | orientation.quaternion = odom->pose.pose.orientation; 562 | 563 | common_handlers_->publishers.publishOrientation(orientation); 564 | } 565 | 566 | // | -------------------- publish velocity -------------------- | 567 | 568 | if (_capabilities_.produces_velocity) { 569 | 570 | geometry_msgs::Vector3Stamped velocity; 571 | 572 | velocity.header.stamp = odom->header.stamp; 573 | velocity.header.frame_id = _uav_name_ + "/" + _body_frame_name_; 574 | velocity.vector = odom->twist.twist.linear; 575 | 576 | common_handlers_->publishers.publishVelocity(velocity); 577 | } 578 | 579 | // | ---------------- publish angular velocity ---------------- | 580 | 581 | if (_capabilities_.produces_angular_velocity) { 582 | 583 | geometry_msgs::Vector3Stamped angular_velocity; 584 | 585 | angular_velocity.header.stamp = odom->header.stamp; 586 | angular_velocity.header.frame_id = _uav_name_ + "/" + _body_frame_name_; 587 | angular_velocity.vector = odom->twist.twist.angular; 588 | 589 | common_handlers_->publishers.publishAngularVelocity(angular_velocity); 590 | } 591 | 592 | // | -------------------- publish odometry -------------------- | 593 | 594 | if (_capabilities_.produces_odometry) { 595 | common_handlers_->publishers.publishOdometry(*odom); 596 | } 597 | 598 | // | ------------------ publish ground truth ------------------ | 599 | 600 | if (_capabilities_.produces_ground_truth) { 601 | common_handlers_->publishers.publishGroundTruth(*odom); 602 | } 603 | 604 | // | ---------------------- publish gnss ---------------------- | 605 | 606 | if (_capabilities_.produces_gnss) { 607 | 608 | double lat; 609 | double lon; 610 | 611 | mrs_lib::UTMtoLL(odom->pose.pose.position.y + _utm_y_, odom->pose.pose.position.x + _utm_x_, _utm_zone_, lat, lon); 612 | 613 | sensor_msgs::NavSatFix gnss; 614 | 615 | gnss.header.stamp = odom->header.stamp; 616 | gnss.header.frame_id = _uav_name_ + "/" + _body_frame_name_; 617 | 618 | gnss.latitude = lat; 619 | gnss.longitude = lon; 620 | gnss.altitude = odom->pose.pose.position.z + _amsl_; 621 | 622 | common_handlers_->publishers.publishGNSS(gnss); 623 | } 624 | 625 | // | ----------------------- publish rtk ---------------------- | 626 | 627 | if (_capabilities_.produces_rtk) { 628 | 629 | double lat; 630 | double lon; 631 | 632 | mrs_lib::UTMtoLL(odom->pose.pose.position.y + _utm_y_, odom->pose.pose.position.x + _utm_x_, _utm_zone_, lat, lon); 633 | 634 | mrs_msgs::RtkGps rtk; 635 | 636 | rtk.header.stamp = odom->header.stamp; 637 | 638 | rtk.gps.latitude = lat; 639 | rtk.gps.longitude = lon; 640 | rtk.gps.altitude = odom->pose.pose.position.z + _amsl_; 641 | 642 | rtk.fix_type.fix_type = mrs_msgs::RtkFixType::RTK_FIX; 643 | 644 | common_handlers_->publishers.publishRTK(rtk); 645 | } 646 | 647 | // | ------------------ publish amsl altitude ----------------- | 648 | 649 | if (_capabilities_.produces_altitude) { 650 | 651 | mrs_msgs::HwApiAltitude altitude; 652 | 653 | altitude.stamp = odom->header.stamp; 654 | 655 | altitude.amsl = odom->pose.pose.position.z + _amsl_; 656 | 657 | common_handlers_->publishers.publishAltitude(altitude); 658 | } 659 | 660 | // | --------------------- publish heading -------------------- | 661 | 662 | if (_capabilities_.produces_magnetometer_heading) { 663 | 664 | double heading = mrs_lib::AttitudeConverter(odom->pose.pose.orientation).getHeading(); 665 | 666 | mrs_msgs::Float64Stamped hdg; 667 | 668 | hdg.header.stamp = ros::Time::now(); 669 | hdg.value = heading; 670 | 671 | common_handlers_->publishers.publishMagnetometerHeading(hdg); 672 | } 673 | } 674 | 675 | //} 676 | 677 | /* callbackImu() //{ */ 678 | 679 | void Api::callbackImu(const sensor_msgs::Imu::ConstPtr msg) { 680 | 681 | if (!is_initialized_) { 682 | return; 683 | } 684 | 685 | ROS_INFO_ONCE("[Api]: getting IMU"); 686 | 687 | if (_capabilities_.produces_imu) { 688 | 689 | common_handlers_->publishers.publishIMU(*msg); 690 | } 691 | } 692 | 693 | //} 694 | 695 | // | ------------------------- timers ------------------------- | 696 | 697 | /* timerMain() //{ */ 698 | 699 | void Api::timerMain([[maybe_unused]] const ros::TimerEvent& event) { 700 | 701 | if (!is_initialized_) { 702 | return; 703 | } 704 | 705 | ROS_INFO_ONCE("[Api]: main timer spinning"); 706 | 707 | publishBatteryState(); 708 | 709 | publishRC(); 710 | } 711 | 712 | //} 713 | 714 | // | ------------------------- methods ------------------------ | 715 | 716 | /* publishBatteryState() //{ */ 717 | 718 | void Api::publishBatteryState(void) { 719 | 720 | if (_capabilities_.produces_battery_state) { 721 | 722 | sensor_msgs::BatteryState msg; 723 | 724 | msg.capacity = 100; 725 | msg.current = 10.0; 726 | msg.voltage = 15.8; 727 | msg.charge = 0.8; 728 | 729 | common_handlers_->publishers.publishBatteryState(msg); 730 | } 731 | } 732 | 733 | //} 734 | 735 | /* publishRC() //{ */ 736 | 737 | void Api::publishRC(void) { 738 | 739 | if (_capabilities_.produces_rc_channels) { 740 | 741 | mrs_msgs::HwApiRcChannels rc; 742 | 743 | rc.stamp = ros::Time::now(); 744 | 745 | rc.channels.push_back(0); 746 | rc.channels.push_back(0); 747 | rc.channels.push_back(0); 748 | rc.channels.push_back(0); 749 | rc.channels.push_back(0); 750 | rc.channels.push_back(0); 751 | rc.channels.push_back(0); 752 | rc.channels.push_back(0); 753 | 754 | common_handlers_->publishers.publishRcChannels(rc); 755 | } 756 | } 757 | 758 | //} 759 | 760 | /* MrsUavHwApi() //{ */ 761 | 762 | void Api::timeoutInputs(void) { 763 | } 764 | 765 | //} 766 | 767 | } // namespace mrs_uav_unreal_simulation 768 | 769 | #include 770 | PLUGINLIB_EXPORT_CLASS(mrs_uav_unreal_simulation::Api, mrs_uav_hw_api::MrsUavHwApi) 771 | -------------------------------------------------------------------------------- /srv/SetOrientation.srv: -------------------------------------------------------------------------------- 1 | geometry_msgs/QuaternionStamped quaternion 2 | --- 3 | bool success 4 | string message 5 | -------------------------------------------------------------------------------- /tmux/one_drone/config/custom_config.yaml: -------------------------------------------------------------------------------- 1 | # GET ALL PARAMETERS USABLE FOR CUSTOM CONFIG BY RUNNING: 2 | ## -------------------------------------------------------------- 3 | ## | rosrun mrs_uav_core get_public_params.py # 4 | ## -------------------------------------------------------------- 5 | 6 | mrs_uav_managers: 7 | 8 | estimation_manager: 9 | 10 | # loaded state estimator plugins 11 | state_estimators: [ 12 | "gps_baro", 13 | ] 14 | 15 | initial_state_estimator: "gps_baro" # will be used as the first state estimator 16 | agl_height_estimator: "" # only slightly filtered height for checking min height (not used in control feedback) 17 | 18 | uav_manager: 19 | 20 | takeoff: 21 | 22 | during_takeoff: 23 | controller: "MpcController" 24 | tracker: "LandoffTracker" 25 | 26 | after_takeoff: 27 | controller: "Se3Controller" 28 | tracker: "MpcTracker" 29 | 30 | midair_activation: 31 | 32 | during_activation: 33 | controller: "MidairActivationController" 34 | tracker: "MidairActivationTracker" 35 | 36 | after_activation: 37 | controller: "Se3Controller" 38 | tracker: "MpcTracker" 39 | -------------------------------------------------------------------------------- /tmux/one_drone/config/network_config.yaml: -------------------------------------------------------------------------------- 1 | # 1. This list is used by NimbroNetwork for mutual communication of the UAVs 2 | # The names of the robots have to match hostnames described in /etc/hosts. 3 | # 4 | # 2. This list is used by MpcTracker for mutual collision avoidance of the UAVs. 5 | # The names should match the true "UAV_NAMES" (the topic prefixes). 6 | # 7 | # network_config:=~/config/network_config.yaml 8 | # 9 | # to the core.launch and nimbro.launch. 10 | 11 | network: 12 | 13 | robot_names: [ 14 | uav1, 15 | ] 16 | -------------------------------------------------------------------------------- /tmux/one_drone/config/octomap_planner.yaml: -------------------------------------------------------------------------------- 1 | safe_obstacle_distance: 1.2 # [m] 2 | euclidean_distance_cutoff: 1.2 # [m] 3 | max_altitude: 5.0 # [m] 4 | 5 | subt_planner: 6 | use: true 7 | -------------------------------------------------------------------------------- /tmux/one_drone/config/octomap_server.yaml: -------------------------------------------------------------------------------- 1 | resolution: 0.4 2 | 3 | # for point cloud raycasting 4 | sensor_params: 5 | 6 | 3d_lidar: 7 | 8 | n_sensors: 1 9 | 10 | sensor_0: 11 | 12 | max_range: 20.0 # [m] max range of points to be included as occupied, free space is updated up to min(max_range, free_ray_distance) 13 | free_ray_distance: 10.0 # [m] max distance for free space raycasting 14 | 15 | vertical_fov_angle: deg(90) 16 | 17 | # fallback values used for free space raycasting for missing data, uses pointcloud dimensions from the incoming message by default 18 | vertical_rays: 128 19 | horizontal_rays: 128 20 | 21 | # what to do when data in the organized pointcloud is missing (is nan) 22 | unknown_rays: 23 | update_free_space: true # update free space when data at the specific point is missing? 24 | clear_occupied: false # clear occupied voxels using unknown rays? BEWARE, setting this to true is very DANGEROUS 25 | free_ray_distance_unknown: 10.0 # [m] ray length for raycasting 26 | -------------------------------------------------------------------------------- /tmux/one_drone/config/simulator.yaml: -------------------------------------------------------------------------------- 1 | uav_names: [ 2 | "uav1", 3 | ] 4 | 5 | graphics_settings: "low" 6 | 7 | # world_name: "warehouse" # works 8 | world_name: "valley" # works 9 | 10 | # TODO 11 | # world_name: "cave" # does not work 12 | # world_name: "dead_spruce_forest" # does not work 13 | # world_name: "infinite_forest" # does not work 14 | # world_name: "forest" # does not work 15 | 16 | weather_type: "sunny" 17 | 18 | daytime: 19 | hour: 7 20 | minute: 30 21 | 22 | uav1: 23 | frame: "x500" 24 | type: "x500" 25 | spawn: 26 | x: 0.0 27 | y: 0.0 28 | z: 0.0 29 | heading: 0.0 30 | 31 | sensors: 32 | 33 | lidar: 34 | enabled: true 35 | # horizontal_rays: 256 # [-] 36 | # vertical_rays: 128 # [-] 37 | horizontal_rays: 128 # [-] 38 | vertical_rays: 32 # [-] 39 | offset_x: 0.0 # [m] 40 | offset_y: 0.0 # [m] 41 | offset_z: 0.1 # [m] 42 | rotation_pitch: 0.0 # [deg] 43 | rotation_roll: 0.0 # [deg] 44 | rotation_yaw: 0.0 # [deg] 45 | 46 | lidar_segmented: 47 | enabled: false 48 | rate: 10.0 # [Hz] 49 | 50 | rgb: 51 | enabled: true 52 | rgb_segmented: 53 | enabled: false 54 | rate: 10.0 # [Hz] 55 | 56 | stereo: 57 | enabled: true 58 | -------------------------------------------------------------------------------- /tmux/one_drone/config/world_config.yaml: -------------------------------------------------------------------------------- 1 | world_origin: 2 | 3 | units: "LATLON" # {"UTM, "LATLON"} 4 | 5 | origin_x: 48.316131 6 | origin_y: 11.935897 7 | 8 | safety_area: 9 | 10 | enabled: false 11 | 12 | horizontal: 13 | 14 | # the frame of reference in which the points are expressed 15 | frame_name: "world_origin" 16 | 17 | # polygon 18 | # 19 | # x, y [m] for any frame_name except latlon_origin 20 | # x = latitude, y = longitude [deg] for frame_name=="latlon_origin" 21 | points: [ 22 | -50, -50, 23 | 50, -50, 24 | 50, 50, 25 | -50, 50, 26 | ] 27 | 28 | vertical: 29 | 30 | # the frame of reference in which the max&min z is expressed 31 | frame_name: "world_origin" 32 | 33 | max_z: 15.0 34 | min_z: 0.5 35 | -------------------------------------------------------------------------------- /tmux/one_drone/kill.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Absolute path to this script. /home/user/bin/foo.sh 4 | SCRIPT=$(readlink -f $0) 5 | # Absolute path this script is in. /home/user/bin 6 | SCRIPTPATH=`dirname $SCRIPT` 7 | cd "$SCRIPTPATH" 8 | 9 | export TMUX_SESSION_NAME=simulation 10 | export TMUX_SOCKET_NAME=mrs 11 | 12 | # just attach to the session 13 | tmux -L $TMUX_SOCKET_NAME split-window -t $TMUX_SESSION_NAME 14 | tmux -L $TMUX_SOCKET_NAME send-keys -t $TMUX_SESSION_NAME "sleep 1; tmux list-panes -s -F \"#{pane_pid} #{pane_current_command}\" | grep -v tmux | cut -d\" \" -f1 | while read in; do killp \$in; done; exit" ENTER 15 | -------------------------------------------------------------------------------- /tmux/one_drone/layout.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "border": "normal", 4 | "floating": "auto_off", 5 | "fullscreen_mode": 0, 6 | "layout": "splitv", 7 | "percent": 0.285714285714286, 8 | "type": "con", 9 | "nodes": [ 10 | { 11 | "border": "pixel", 12 | "current_border_width": 3, 13 | "floating": "auto_off", 14 | "geometry": { 15 | "height": 1030, 16 | "width": 936, 17 | "x": 4806, 18 | "y": 32 19 | }, 20 | "name": "rviz.rviz* - RViz", 21 | "percent": 0.5, 22 | "swallows": [ 23 | { 24 | "instance": "^rviz$" 25 | } 26 | ], 27 | "type": "con" 28 | }, 29 | { 30 | "border": "pixel", 31 | "current_border_width": 3, 32 | "floating": "auto_off", 33 | "geometry": { 34 | "height": 460, 35 | "width": 724, 36 | "x": 0, 37 | "y": 0 38 | }, 39 | "name": "./start.sh", 40 | "percent": 0.5, 41 | "swallows": [ 42 | { 43 | "instance": "^urxvt$" 44 | } 45 | ], 46 | "type": "con" 47 | } 48 | ] 49 | } 50 | ] 51 | -------------------------------------------------------------------------------- /tmux/one_drone/rviz.rviz: -------------------------------------------------------------------------------- 1 | Panels: 2 | - Class: rviz/Displays 3 | Help Height: 0 4 | Name: Displays 5 | Property Tree Widget: 6 | Expanded: 7 | - /TF1/Frames1 8 | - /TF1/Tree1 9 | Splitter Ratio: 0.7833572626113892 10 | Tree Height: 352 11 | - Class: rviz/Selection 12 | Name: Selection 13 | - Class: rviz/Tool Properties 14 | Expanded: 15 | - /2D Pose Estimate1 16 | - /2D Nav Goal1 17 | - /Publish Point1 18 | - /Plan path1 19 | - /Custom Goal1 20 | Name: Tool Properties 21 | Splitter Ratio: 0.5886790156364441 22 | - Class: rviz/Views 23 | Expanded: 24 | - /Current View1 25 | Name: Views 26 | Splitter Ratio: 0.5 27 | - Class: rviz/Time 28 | Name: Time 29 | SyncMode: 0 30 | SyncSource: lidar 31 | Preferences: 32 | PromptSaveOnExit: true 33 | Toolbars: 34 | toolButtonStyle: 2 35 | Visualization Manager: 36 | Class: "" 37 | Displays: 38 | - Alpha: 0.20000000298023224 39 | Cell Size: 1 40 | Class: rviz/Grid 41 | Color: 160; 160; 164 42 | Enabled: true 43 | Line Style: 44 | Line Width: 0.029999999329447746 45 | Value: Lines 46 | Name: Grid 47 | Normal Cell Count: 0 48 | Offset: 49 | X: 0 50 | Y: 0 51 | Z: 0 52 | Plane: XY 53 | Plane Cell Count: 100 54 | Reference Frame: 55 | Value: true 56 | - Alpha: 0.5 57 | Cell Size: 5 58 | Class: rviz/Grid 59 | Color: 160; 160; 164 60 | Enabled: true 61 | Line Style: 62 | Line Width: 0.029999999329447746 63 | Value: Lines 64 | Name: Grid 65 | Normal Cell Count: 0 66 | Offset: 67 | X: 0 68 | Y: 0 69 | Z: 0 70 | Plane: XY 71 | Plane Cell Count: 100 72 | Reference Frame: 73 | Value: true 74 | - Class: rviz/TF 75 | Enabled: false 76 | Filter (blacklist): "" 77 | Filter (whitelist): "" 78 | Frame Timeout: 15 79 | Frames: 80 | All Enabled: false 81 | Marker Alpha: 1 82 | Marker Scale: 1 83 | Name: TF 84 | Show Arrows: true 85 | Show Axes: true 86 | Show Names: true 87 | Tree: 88 | {} 89 | Update Interval: 0 90 | Value: false 91 | - Alpha: 1 92 | Class: rviz/RobotModel 93 | Collision Enabled: false 94 | Enabled: true 95 | Links: 96 | All Links Enabled: true 97 | Expand Joint Details: false 98 | Expand Link Details: false 99 | Expand Tree: false 100 | Link Tree Style: Links in Alphabetic Order 101 | uav1/fcu: 102 | Alpha: 1 103 | Show Axes: false 104 | Show Trail: false 105 | Value: true 106 | uav1/fcu/arms_red: 107 | Alpha: 1 108 | Show Axes: false 109 | Show Trail: false 110 | Value: true 111 | Name: UAVModel 112 | Robot Description: /uav1/robot_model 113 | TF Prefix: "" 114 | Update Interval: 0 115 | Value: true 116 | Visual Enabled: true 117 | - Class: rviz/Group 118 | Displays: 119 | - Background color: 204; 204; 204 120 | Class: mrs_rviz_plugins/Status 121 | Computer load: true 122 | Control manager: true 123 | Custom strings: true 124 | Enabled: true 125 | Hw api state: true 126 | Name: Status 127 | Node stats list: false 128 | Odometry: true 129 | Text color: 0; 0; 0 130 | Top Line: true 131 | Topic rates: true 132 | UAV name: uav1 133 | Value: true 134 | - Class: rviz/InteractiveMarkers 135 | Enable Transparency: true 136 | Enabled: true 137 | Name: Control Display 138 | Show Axes: false 139 | Show Descriptions: true 140 | Show Visual Aids: false 141 | Update Topic: control/update 142 | Value: true 143 | Enabled: false 144 | Name: Status 145 | - Class: rviz/Group 146 | Displays: 147 | - Alpha: 1 148 | Autocompute Intensity Bounds: true 149 | Autocompute Value Bounds: 150 | Max Value: 6.5032958984375 151 | Min Value: -0.6449446678161621 152 | Value: true 153 | Axis: Z 154 | Channel Name: intensity 155 | Class: rviz/PointCloud2 156 | Color: 255; 255; 255 157 | Color Transformer: AxisColor 158 | Decay Time: 0 159 | Enabled: true 160 | Invert Rainbow: false 161 | Max Color: 255; 255; 255 162 | Min Color: 0; 0; 0 163 | Name: ouster_raw 164 | Position Transformer: XYZ 165 | Queue Size: 10 166 | Selectable: true 167 | Size (Pixels): 3 168 | Size (m): 0.10000000149011612 169 | Style: Spheres 170 | Topic: /uav1/os_cloud_nodelet/points 171 | Unreliable: true 172 | Use Fixed Frame: true 173 | Use rainbow: true 174 | Value: true 175 | - Alpha: 1 176 | Autocompute Intensity Bounds: true 177 | Autocompute Value Bounds: 178 | Max Value: 10 179 | Min Value: -10 180 | Value: true 181 | Axis: Z 182 | Channel Name: intensity 183 | Class: rviz/LaserScan 184 | Color: 0; 0; 0 185 | Color Transformer: FlatColor 186 | Decay Time: 0 187 | Enabled: true 188 | Invert Rainbow: false 189 | Max Color: 255; 255; 255 190 | Min Color: 0; 0; 0 191 | Name: rplidar 192 | Position Transformer: XYZ 193 | Queue Size: 10 194 | Selectable: true 195 | Size (Pixels): 3 196 | Size (m): 0.10000000149011612 197 | Style: Flat Squares 198 | Topic: /uav1/rplidar/scan 199 | Unreliable: true 200 | Use Fixed Frame: true 201 | Use rainbow: true 202 | Value: true 203 | - Class: rviz/Image 204 | Enabled: false 205 | Image Topic: /uav1/vio/camera/image_raw 206 | Max Value: 1 207 | Median window: 5 208 | Min Value: 0 209 | Name: vio_camera 210 | Normalize Range: true 211 | Queue Size: 2 212 | Transport Hint: raw 213 | Unreliable: false 214 | Value: false 215 | Enabled: true 216 | Name: Sensors 217 | - Class: rviz/Group 218 | Displays: 219 | - Class: rviz/MarkerArray 220 | Enabled: true 221 | Marker Topic: /uav1/control_manager/safety_area_markers 222 | Name: SafetyhArea 223 | Namespaces: 224 | {} 225 | Queue Size: 100 226 | Value: true 227 | - Class: rviz/MarkerArray 228 | Enabled: true 229 | Marker Topic: /uav1/control_manager/safety_area_coordinates_markers 230 | Name: SafetyAreaCoordinates 231 | Namespaces: 232 | {} 233 | Queue Size: 100 234 | Value: true 235 | - Class: rviz/MarkerArray 236 | Enabled: true 237 | Marker Topic: /uav1/control_manager/disturbances_markers 238 | Name: Disturbances 239 | Namespaces: 240 | control_manager: true 241 | Queue Size: 100 242 | Value: true 243 | - Angle Tolerance: 0.009999999776482582 244 | Class: rviz/Odometry 245 | Covariance: 246 | Orientation: 247 | Alpha: 0.5 248 | Color: 255; 255; 127 249 | Color Style: Unique 250 | Frame: Local 251 | Offset: 1 252 | Scale: 1 253 | Value: true 254 | Position: 255 | Alpha: 0.30000001192092896 256 | Color: 204; 51; 204 257 | Scale: 1 258 | Value: true 259 | Value: true 260 | Enabled: true 261 | Keep: 1 262 | Name: control_reference 263 | Position Tolerance: 0.009999999776482582 264 | Queue Size: 10 265 | Shape: 266 | Alpha: 1 267 | Axes Length: 1 268 | Axes Radius: 0.10000000149011612 269 | Color: 255; 25; 0 270 | Head Length: 0.30000001192092896 271 | Head Radius: 0.10000000149011612 272 | Shaft Length: 1 273 | Shaft Radius: 0.05000000074505806 274 | Value: Axes 275 | Topic: /uav1/control_manager/control_reference 276 | Unreliable: true 277 | Value: true 278 | - Class: rviz/Group 279 | Displays: 280 | - Alpha: 1 281 | Arrow Length: 0.30000001192092896 282 | Axes Length: 0.30000001192092896 283 | Axes Radius: 0.009999999776482582 284 | Class: rviz/PoseArray 285 | Color: 0; 170; 0 286 | Enabled: true 287 | Head Length: 0.07000000029802322 288 | Head Radius: 0.029999999329447746 289 | Name: Poses 290 | Queue Size: 10 291 | Shaft Length: 0.23000000417232513 292 | Shaft Radius: 0.009999999776482582 293 | Shape: Arrow (Flat) 294 | Topic: /uav1/control_manager/trajectory_original/poses 295 | Unreliable: true 296 | Value: true 297 | - Class: rviz/MarkerArray 298 | Enabled: true 299 | Marker Topic: /uav1/control_manager/trajectory_original/markers 300 | Name: Markers 301 | Namespaces: 302 | {} 303 | Queue Size: 100 304 | Value: true 305 | Enabled: true 306 | Name: OriginalTrajectory 307 | - Alpha: 0.10000000149011612 308 | Class: mrs_rviz_plugins/Bumper 309 | Collision alpha: 0.5 310 | Collision color: 255; 0; 0 311 | Color: 204; 51; 204 312 | Colorize collisions: true 313 | Display mode: sensor types 314 | Enabled: true 315 | History Length: 1 316 | Horizontal collision threshold: 1 317 | Name: Bumper 318 | Queue Size: 10 319 | Show sectors with no data: false 320 | Show undetected obstacles: true 321 | Topic: /uav1/bumper/obstacle_sectors 322 | Unreliable: true 323 | Value: true 324 | Vertical collision threshold: 1 325 | Enabled: true 326 | Name: ControlManager 327 | - Class: rviz/Group 328 | Displays: 329 | - Angle Tolerance: 0.009999999776482582 330 | Class: rviz/Odometry 331 | Covariance: 332 | Orientation: 333 | Alpha: 0.5 334 | Color: 255; 255; 127 335 | Color Style: Unique 336 | Frame: Local 337 | Offset: 1 338 | Scale: 1 339 | Value: true 340 | Position: 341 | Alpha: 0.30000001192092896 342 | Color: 204; 51; 204 343 | Scale: 1 344 | Value: true 345 | Value: false 346 | Enabled: true 347 | Keep: 1 348 | Name: odom_main 349 | Position Tolerance: 0.009999999776482582 350 | Queue Size: 10 351 | Shape: 352 | Alpha: 1 353 | Axes Length: 0.5 354 | Axes Radius: 0.10000000149011612 355 | Color: 0; 25; 255 356 | Head Length: 1 357 | Head Radius: 0.30000001192092896 358 | Shaft Length: 1 359 | Shaft Radius: 0.05000000074505806 360 | Value: Axes 361 | Topic: /uav1/estimation_manager/odom_main 362 | Unreliable: true 363 | Value: true 364 | Enabled: true 365 | Name: EstimationManager 366 | - Class: rviz/Group 367 | Displays: 368 | - Alpha: 1 369 | Arrow Length: 0.30000001192092896 370 | Axes Length: 0.30000001192092896 371 | Axes Radius: 0.009999999776482582 372 | Class: rviz/PoseArray 373 | Color: 0; 0; 255 374 | Enabled: true 375 | Head Length: 0.07000000029802322 376 | Head Radius: 0.029999999329447746 377 | Name: MpcPredictionTrajectory 378 | Queue Size: 10 379 | Shaft Length: 0.23000000417232513 380 | Shaft Radius: 0.009999999776482582 381 | Shape: Arrow (Flat) 382 | Topic: /uav1/control_manager/mpc_tracker/predicted_trajectory_debugging 383 | Unreliable: true 384 | Value: true 385 | - Alpha: 1 386 | Arrow Length: 0.30000001192092896 387 | Axes Length: 0.10000000149011612 388 | Axes Radius: 0.05000000074505806 389 | Class: rviz/PoseArray 390 | Color: 255; 25; 0 391 | Enabled: true 392 | Head Length: 0.07000000029802322 393 | Head Radius: 0.029999999329447746 394 | Name: MpcInnerReference 395 | Queue Size: 10 396 | Shaft Length: 0.23000000417232513 397 | Shaft Radius: 0.009999999776482582 398 | Shape: Axes 399 | Topic: /uav1/control_manager/mpc_tracker/mpc_reference_debugging 400 | Unreliable: true 401 | Value: true 402 | - Class: rviz/Group 403 | Displays: 404 | - Alpha: 1 405 | Arrow Length: 0.30000001192092896 406 | Axes Length: 0.30000001192092896 407 | Axes Radius: 0.009999999776482582 408 | Class: rviz/PoseArray 409 | Color: 255; 25; 0 410 | Enabled: true 411 | Head Length: 0.07000000029802322 412 | Head Radius: 0.029999999329447746 413 | Name: Poses 414 | Queue Size: 10 415 | Shaft Length: 0.23000000417232513 416 | Shaft Radius: 0.009999999776482582 417 | Shape: Arrow (Flat) 418 | Topic: /uav1/control_manager/mpc_tracker/trajectory_processed/poses 419 | Unreliable: true 420 | Value: true 421 | - Class: rviz/MarkerArray 422 | Enabled: true 423 | Marker Topic: /uav1/control_manager/mpc_tracker/trajectory_processed/markers 424 | Name: Markers 425 | Namespaces: 426 | {} 427 | Queue Size: 100 428 | Value: true 429 | Enabled: true 430 | Name: PostprocessedTrajectory 431 | Enabled: true 432 | Name: MpcTracker 433 | - Class: rviz/Group 434 | Displays: 435 | - Class: rviz/MarkerArray 436 | Enabled: true 437 | Marker Topic: /uav1/trajectory_generation/markers/final 438 | Name: final 439 | Namespaces: 440 | {} 441 | Queue Size: 100 442 | Value: true 443 | - Class: rviz/MarkerArray 444 | Enabled: true 445 | Marker Topic: /uav1/trajectory_generation/markers/original 446 | Name: original 447 | Namespaces: 448 | {} 449 | Queue Size: 100 450 | Value: true 451 | Enabled: true 452 | Name: TrajectoryGeneration 453 | - Class: rviz/Image 454 | Enabled: false 455 | Image Topic: /uav1/rgb_segmented/image_raw 456 | Max Value: 1 457 | Median window: 5 458 | Min Value: 0 459 | Name: rgb_segmented 460 | Normalize Range: true 461 | Queue Size: 2 462 | Transport Hint: raw 463 | Unreliable: false 464 | Value: false 465 | - Class: rviz/Image 466 | Enabled: true 467 | Image Topic: /uav1/rgb/image_raw 468 | Max Value: 1 469 | Median window: 5 470 | Min Value: 0 471 | Name: rgb 472 | Normalize Range: true 473 | Queue Size: 2 474 | Transport Hint: raw 475 | Unreliable: false 476 | Value: true 477 | - Class: rviz/Image 478 | Enabled: false 479 | Image Topic: /uav1/stereo/right/image_raw 480 | Max Value: 1 481 | Median window: 5 482 | Min Value: 0 483 | Name: stereo_right 484 | Normalize Range: true 485 | Queue Size: 2 486 | Transport Hint: raw 487 | Unreliable: false 488 | Value: false 489 | - Class: rviz/Image 490 | Enabled: false 491 | Image Topic: /uav1/stereo/left/image_raw 492 | Max Value: 1 493 | Median window: 5 494 | Min Value: 0 495 | Name: stereo_left 496 | Normalize Range: true 497 | Queue Size: 2 498 | Transport Hint: raw 499 | Unreliable: false 500 | Value: false 501 | - Alpha: 1 502 | Autocompute Intensity Bounds: true 503 | Autocompute Value Bounds: 504 | Max Value: 10 505 | Min Value: -10 506 | Value: true 507 | Axis: Z 508 | Channel Name: intensity 509 | Class: rviz/PointCloud2 510 | Color: 255; 255; 255 511 | Color Transformer: RGB8 512 | Decay Time: 0 513 | Enabled: true 514 | Invert Rainbow: false 515 | Max Color: 255; 255; 255 516 | Min Color: 0; 0; 0 517 | Name: stereo_cloud 518 | Position Transformer: XYZ 519 | Queue Size: 10 520 | Selectable: true 521 | Size (Pixels): 3 522 | Size (m): 0.10000000149011612 523 | Style: Flat Squares 524 | Topic: /uav1/stereo/points2 525 | Unreliable: false 526 | Use Fixed Frame: true 527 | Use rainbow: true 528 | Value: true 529 | - Alpha: 1 530 | Autocompute Intensity Bounds: true 531 | Autocompute Value Bounds: 532 | Max Value: 8.906384468078613 533 | Min Value: -0.026181578636169434 534 | Value: true 535 | Axis: Z 536 | Channel Name: intensity 537 | Class: rviz/PointCloud2 538 | Color: 255; 255; 255 539 | Color Transformer: AxisColor 540 | Decay Time: 0 541 | Enabled: true 542 | Invert Rainbow: false 543 | Max Color: 255; 255; 255 544 | Min Color: 0; 0; 0 545 | Name: lidar 546 | Position Transformer: XYZ 547 | Queue Size: 10 548 | Selectable: true 549 | Size (Pixels): 3 550 | Size (m): 0.10000000149011612 551 | Style: Flat Squares 552 | Topic: /uav1/lidar/points 553 | Unreliable: false 554 | Use Fixed Frame: true 555 | Use rainbow: true 556 | Value: true 557 | - Alpha: 1 558 | Autocompute Intensity Bounds: true 559 | Autocompute Value Bounds: 560 | Max Value: 12.273218154907227 561 | Min Value: -3.3037233352661133 562 | Value: true 563 | Axis: Z 564 | Channel Name: intensity 565 | Class: rviz/PointCloud2 566 | Color: 255; 255; 255 567 | Color Transformer: RGB8 568 | Decay Time: 0 569 | Enabled: false 570 | Invert Rainbow: false 571 | Max Color: 255; 255; 255 572 | Min Color: 0; 0; 0 573 | Name: lidar_segmented 574 | Position Transformer: XYZ 575 | Queue Size: 10 576 | Selectable: true 577 | Size (Pixels): 3 578 | Size (m): 0.10000000149011612 579 | Style: Flat Squares 580 | Topic: /uav1/lidar_segmented/points 581 | Unreliable: false 582 | Use Fixed Frame: true 583 | Use rainbow: true 584 | Value: false 585 | - Alpha: 1 586 | Autocompute Intensity Bounds: true 587 | Autocompute Value Bounds: 588 | Max Value: 10 589 | Min Value: -10 590 | Value: true 591 | Axis: Z 592 | Channel Name: intensity 593 | Class: rviz/PointCloud2 594 | Color: 255; 255; 255 595 | Color Transformer: Intensity 596 | Decay Time: 0 597 | Enabled: true 598 | Invert Rainbow: false 599 | Max Color: 255; 255; 255 600 | Min Color: 0; 0; 0 601 | Name: lidar_intensity 602 | Position Transformer: XYZ 603 | Queue Size: 10 604 | Selectable: true 605 | Size (Pixels): 3 606 | Size (m): 0.10000000149011612 607 | Style: Flat Squares 608 | Topic: /uav1/lidar_intensity/points 609 | Unreliable: false 610 | Use Fixed Frame: true 611 | Use rainbow: true 612 | Value: true 613 | - Class: rviz/MarkerArray 614 | Enabled: true 615 | Marker Topic: /uav1/octomap_global_vis/occupied_cells_vis_array_throttled 616 | Name: global_map 617 | Namespaces: 618 | map: true 619 | Queue Size: 100 620 | Value: true 621 | - Class: rviz/MarkerArray 622 | Enabled: false 623 | Marker Topic: /uav1/octomap_local_vis/occupied_cells_vis_array 624 | Name: local_map 625 | Namespaces: 626 | {} 627 | Queue Size: 100 628 | Value: false 629 | Enabled: true 630 | Global Options: 631 | Background Color: 255; 255; 255 632 | Default Light: true 633 | Fixed Frame: uav1/world_origin 634 | Frame Rate: 60 635 | Name: root 636 | Tools: 637 | - Class: rviz/Interact 638 | Hide Inactive Objects: true 639 | - Class: rviz/MoveCamera 640 | - Class: rviz/Select 641 | - Class: rviz/FocusCamera 642 | - Class: rviz/Measure 643 | - Class: rviz/SetInitialPose 644 | Theta std deviation: 0.2617993950843811 645 | Topic: /initialpose 646 | X std deviation: 0.5 647 | Y std deviation: 0.5 648 | - Class: rviz/SetGoal 649 | Topic: /move_base_simple/goal 650 | - Class: rviz/PublishPoint 651 | Single click: true 652 | Topic: /clicked_point 653 | - Class: mrs_rviz_plugins/ControlTool 654 | - Class: mrs_rviz_plugins/WaypointPlanner 655 | Drone name: uav1 656 | Fly now: true 657 | Height offset: 0 658 | Loop: false 659 | Shape: Axes 660 | Stop at waypoints: false 661 | Topic: trajectory_generation/path 662 | Use heading: true 663 | - Class: mrs_rviz_plugins/NamedSetGoal 664 | Name: name 665 | Topic: goal 666 | Value: true 667 | Views: 668 | Current: 669 | Class: rviz/Orbit 670 | Distance: 8.310941696166992 671 | Enable Stereo Rendering: 672 | Stereo Eye Separation: 0.05999999865889549 673 | Stereo Focal Distance: 1 674 | Swap Stereo Eyes: false 675 | Value: false 676 | Field of View: 0.7853981852531433 677 | Focal Point: 678 | X: -0.48207715153694153 679 | Y: -0.006430231034755707 680 | Z: 0.5115839838981628 681 | Focal Shape Fixed Size: true 682 | Focal Shape Size: 0.05000000074505806 683 | Invert Z Axis: false 684 | Name: Current View 685 | Near Clip Distance: 0.009999999776482582 686 | Pitch: 0.5753988027572632 687 | Target Frame: uav1/fcu 688 | Yaw: 2.4654572010040283 689 | Saved: ~ 690 | Window Geometry: 691 | Displays: 692 | collapsed: false 693 | Height: 686 694 | Hide Left Dock: false 695 | Hide Right Dock: true 696 | QMainWindow State: 000000ff00000000fd0000000400000000000001bf00000260fc020000000efb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005700fffffffb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003400000197000000b900fffffffb0000001400760069006f005f00630061006d0065007200610000000122000000bd0000001600fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000600720067006201000001d0000000c40000001600fffffffb0000001400760069006f005f00630061006d00650072006100000001400000009f0000000000000000fb0000001a007200670062005f007300650067006d0065006e007400650064000000019d000000f70000001600fffffffb0000001600730074006500720065006f005f006c006500660074000000023c000000580000001600fffffffb0000001800730074006500720065006f005f0072006900670068007400000001810000006d0000001600fffffffb0000000a0049006d00610067006501000004d5000000db00000000000000000000000100000116000001a4fc0200000004fb0000001e0054006f006f006c002000500072006f0070006500720074006900650073000000003b000000e40000005700fffffffb0000000a005600690065007700730000000125000000ba0000009600fffffffb0000001e0054006f006f006c002000500072006f0070006500720074006900650073000000016d0000016e0000000000000000fb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000038f0000003efc0100000002fb0000000800540069006d006500000000000000038f0000032700fffffffb0000000800540069006d006501000000000000045000000000000000000000081e0000026000000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 697 | Selection: 698 | collapsed: false 699 | Time: 700 | collapsed: false 701 | Tool Properties: 702 | collapsed: true 703 | Views: 704 | collapsed: true 705 | Width: 2530 706 | X: 1932 707 | Y: 736 708 | rgb: 709 | collapsed: false 710 | rgb_segmented: 711 | collapsed: false 712 | stereo_left: 713 | collapsed: false 714 | stereo_right: 715 | collapsed: false 716 | vio_camera: 717 | collapsed: false 718 | -------------------------------------------------------------------------------- /tmux/one_drone/session.yml: -------------------------------------------------------------------------------- 1 | # do not modify these 2 | root: ./ 3 | name: simulation 4 | socket_name: mrs 5 | attach: false 6 | tmux_options: -f /etc/ctu-mrs/tmux.conf 7 | # you can modify these 8 | pre_window: export UAV_NAME=uav1; export RUN_TYPE=simulation; export UAV_TYPE=x500 9 | startup_window: goto 10 | windows: 11 | - roscore: 12 | layout: tiled 13 | panes: 14 | - roscore 15 | - simulator: 16 | layout: tiled 17 | panes: 18 | - waitForRos; roslaunch mrs_uav_unreal_simulation unreal_simulator.launch custom_config:=./config/simulator.yaml 19 | - hw_api: 20 | layout: tiled 21 | panes: 22 | - waitForTime; roslaunch mrs_uav_unreal_simulation hw_api.launch 23 | - takeoff: 24 | layout: tiled 25 | panes: 26 | - waitForHw; roslaunch mrs_uav_autostart automatic_start.launch 27 | - waitForControl; rosservice call /$UAV_NAME/hw_api/arming 1; sleep 2; rosservice call /$UAV_NAME/hw_api/offboard 28 | # - waitForControl; rosservice call /$UAV_NAME/hw_api/arming 1; rosservice call /$UAV_NAME/uav_manager/midair_activation 29 | - status: 30 | layout: tiled 31 | panes: 32 | - waitForHw; roslaunch mrs_uav_status status.launch 33 | - control: 34 | layout: tiled 35 | panes: 36 | - waitForHw; sleep 5; roslaunch mrs_uav_core core.launch 37 | platform_config:=`rospack find mrs_multirotor_simulator`/config/mrs_uav_system/$UAV_TYPE.yaml 38 | custom_config:=./config/custom_config.yaml 39 | world_config:=./config/world_config.yaml 40 | network_config:=./config/network_config.yaml 41 | - stereo: 42 | layout: tiled 43 | panes: 44 | - waitForHw; roslaunch mrs_uav_unreal_simulation stereo_image_proc.launch 45 | - mapping: 46 | layout: tiled 47 | panes: 48 | - waitForHw; roslaunch mrs_uav_unreal_simulation mapplan.launch 49 | config_octomap_server:=./config/octomap_server.yaml 50 | config_octomap_planner:=./config/octomap_planner.yaml 51 | - goto: 52 | layout: tiled 53 | panes: 54 | - 'history -s rosservice call /$UAV_NAME/octomap_planner/goto \"goal: \[0.0, 60.0, 2.0, 0.0\]\"' 55 | - rviz: 56 | layout: tiled 57 | panes: 58 | - waitForControl; rosrun rviz rviz -d ./rviz.rviz 59 | - waitForControl; roslaunch mrs_rviz_plugins load_robot.launch 60 | - waitForControl; roslaunch mrs_rviz_plugins rviz_interface.launch 61 | - layout: 62 | layout: tiled 63 | panes: 64 | - waitForControl; sleep 5; ~/.i3/layout_manager.sh ./layout.json 65 | 66 | - rqrReconfigure: 67 | layaut: tiled 68 | panes: 69 | - waitForRos; waitForControl; rosrun rqt_reconfigure rqt_reconfigure 70 | -------------------------------------------------------------------------------- /tmux/one_drone/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Absolute path to this script. /home/user/bin/foo.sh 4 | SCRIPT=$(readlink -f $0) 5 | # Absolute path this script is in. /home/user/bin 6 | SCRIPTPATH=`dirname $SCRIPT` 7 | cd "$SCRIPTPATH" 8 | 9 | export TMUX_SESSION_NAME=simulation 10 | export TMUX_SOCKET_NAME=mrs 11 | 12 | # start tmuxinator 13 | tmuxinator start -p ./session.yml 14 | 15 | # if we are not in tmux 16 | if [ -z $TMUX ]; then 17 | 18 | # just attach to the session 19 | tmux -L $TMUX_SOCKET_NAME a -t $TMUX_SESSION_NAME 20 | 21 | # if we are in tmux 22 | else 23 | 24 | # switch to the newly-started session 25 | tmux detach-client -E "tmux -L $TMUX_SOCKET_NAME a -t $TMUX_SESSION_NAME" 26 | 27 | fi 28 | -------------------------------------------------------------------------------- /tmux/two_drones/config/custom_config.yaml: -------------------------------------------------------------------------------- 1 | # GET ALL PARAMETERS USABLE FOR CUSTOM CONFIG BY RUNNING: 2 | ## -------------------------------------------------------------- 3 | ## | rosrun mrs_uav_core get_public_params.py # 4 | ## -------------------------------------------------------------- 5 | 6 | mrs_uav_managers: 7 | 8 | estimation_manager: 9 | 10 | # loaded state estimator plugins 11 | state_estimators: [ 12 | "gps_baro", 13 | ] 14 | 15 | initial_state_estimator: "gps_baro" # will be used as the first state estimator 16 | agl_height_estimator: "" # only slightly filtered height for checking min height (not used in control feedback) 17 | 18 | uav_manager: 19 | 20 | takeoff: 21 | 22 | during_takeoff: 23 | controller: "MpcController" 24 | tracker: "LandoffTracker" 25 | 26 | after_takeoff: 27 | controller: "Se3Controller" 28 | tracker: "MpcTracker" 29 | 30 | midair_activation: 31 | 32 | during_activation: 33 | controller: "MidairActivationController" 34 | tracker: "MidairActivationTracker" 35 | 36 | after_activation: 37 | controller: "Se3Controller" 38 | tracker: "MpcTracker" 39 | -------------------------------------------------------------------------------- /tmux/two_drones/config/network_config.yaml: -------------------------------------------------------------------------------- 1 | # 1. This list is used by NimbroNetwork for mutual communication of the UAVs 2 | # The names of the robots have to match hostnames described in /etc/hosts. 3 | # 4 | # 2. This list is used by MpcTracker for mutual collision avoidance of the UAVs. 5 | # The names should match the true "UAV_NAMES" (the topic prefixes). 6 | # 7 | # network_config:=~/config/network_config.yaml 8 | # 9 | # to the core.launch and nimbro.launch. 10 | 11 | network: 12 | 13 | robot_names: [ 14 | uav1, 15 | uav2, 16 | ] 17 | -------------------------------------------------------------------------------- /tmux/two_drones/config/simulator.yaml: -------------------------------------------------------------------------------- 1 | uavs_mutual_visibility: true 2 | 3 | world_name: "valley" 4 | 5 | weather_type: "sunny" 6 | 7 | frames: 8 | world: 9 | name: "simulator_origin" 10 | prefix_with_uav_name: false 11 | fcu: 12 | name: "fcu" 13 | publish_tf: false 14 | 15 | uav_names: [ 16 | "uav1", 17 | "uav2", 18 | ] 19 | 20 | uav1: 21 | frame: "x500" 22 | type: "x500" 23 | spawn: 24 | x: 0.0 25 | y: 0.0 26 | z: 0.0 27 | heading: 0 28 | 29 | 30 | uav2: 31 | frame: "a300" 32 | type: "x500" 33 | spawn: 34 | x: 6.0 35 | y: 0.0 36 | z: 0.0 37 | heading: 3.14 38 | 39 | sensors: 40 | 41 | rangefinder: 42 | 43 | enabled: true 44 | rate: 10.0 # [Hz] 45 | 46 | lidar: 47 | 48 | enabled: true 49 | 50 | rate: 10.0 # [Hz] 51 | 52 | horizontal_fov_left: 180.0 # [deg] 53 | horizontal_fov_right: 180.0 # [deg] 54 | 55 | vertical_fov_up: 52.0 # [deg] 56 | vertical_fov_down: 7.0 # [deg] 57 | rgb: 58 | enabled: true 59 | stereo: 60 | enabled: false 61 | -------------------------------------------------------------------------------- /tmux/two_drones/config/world_config.yaml: -------------------------------------------------------------------------------- 1 | world_origin: 2 | 3 | units: "LATLON" # {"UTM, "LATLON"} 4 | 5 | origin_x: 48.316131 6 | origin_y: 11.935897 7 | 8 | safety_area: 9 | 10 | enabled: true 11 | 12 | horizontal: 13 | 14 | # the frame of reference in which the points are expressed 15 | frame_name: "world_origin" 16 | 17 | # polygon 18 | # 19 | # x, y [m] for any frame_name except latlon_origin 20 | # x = latitude, y = longitude [deg] for frame_name=="latlon_origin" 21 | points: [ 22 | -50, -50, 23 | 50, -50, 24 | 50, 50, 25 | -50, 50, 26 | ] 27 | 28 | vertical: 29 | 30 | # the frame of reference in which the max&min z is expressed 31 | frame_name: "world_origin" 32 | 33 | max_z: 15.0 34 | min_z: 0.5 35 | -------------------------------------------------------------------------------- /tmux/two_drones/kill.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Absolute path to this script. /home/user/bin/foo.sh 4 | SCRIPT=$(readlink -f $0) 5 | # Absolute path this script is in. /home/user/bin 6 | SCRIPTPATH=`dirname $SCRIPT` 7 | cd "$SCRIPTPATH" 8 | 9 | export TMUX_SESSION_NAME=simulation 10 | export TMUX_SOCKET_NAME=mrs 11 | 12 | # just attach to the session 13 | tmux -L $TMUX_SOCKET_NAME split-window -t $TMUX_SESSION_NAME 14 | tmux -L $TMUX_SOCKET_NAME send-keys -t $TMUX_SESSION_NAME "sleep 1; tmux list-panes -s -F \"#{pane_pid} #{pane_current_command}\" | grep -v tmux | cut -d\" \" -f1 | while read in; do killp \$in; done; exit" ENTER 15 | -------------------------------------------------------------------------------- /tmux/two_drones/layout.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "border": "normal", 4 | "floating": "auto_off", 5 | "fullscreen_mode": 0, 6 | "layout": "splitv", 7 | "percent": 0.285714285714286, 8 | "type": "con", 9 | "nodes": [ 10 | { 11 | "border": "pixel", 12 | "current_border_width": 3, 13 | "floating": "auto_off", 14 | "geometry": { 15 | "height": 1030, 16 | "width": 936, 17 | "x": 4806, 18 | "y": 32 19 | }, 20 | "name": "rviz.rviz* - RViz", 21 | "percent": 0.5, 22 | "swallows": [ 23 | { 24 | "instance": "^rviz$" 25 | } 26 | ], 27 | "type": "con" 28 | }, 29 | { 30 | "border": "pixel", 31 | "current_border_width": 3, 32 | "floating": "auto_off", 33 | "geometry": { 34 | "height": 460, 35 | "width": 724, 36 | "x": 0, 37 | "y": 0 38 | }, 39 | "name": "./start.sh", 40 | "percent": 0.5, 41 | "swallows": [ 42 | { 43 | "instance": "^urxvt$" 44 | } 45 | ], 46 | "type": "con" 47 | } 48 | ] 49 | } 50 | ] 51 | -------------------------------------------------------------------------------- /tmux/two_drones/rviz.rviz: -------------------------------------------------------------------------------- 1 | Panels: 2 | - Class: rviz/Displays 3 | Help Height: 0 4 | Name: Displays 5 | Property Tree Widget: 6 | Expanded: 7 | - /uav11 8 | - /uav21 9 | Splitter Ratio: 0.6970587968826294 10 | Tree Height: 439 11 | - Class: rviz/Selection 12 | Name: Selection 13 | - Class: rviz/Tool Properties 14 | Expanded: 15 | - /2D Pose Estimate1 16 | - /2D Nav Goal1 17 | - /Publish Point1 18 | - /Plan path1 19 | - /Custom Goal1 20 | Name: Tool Properties 21 | Splitter Ratio: 0.5886790156364441 22 | - Class: rviz/Views 23 | Expanded: 24 | - /Current View1 25 | Name: Views 26 | Splitter Ratio: 0.5 27 | - Class: rviz/Time 28 | Name: Time 29 | SyncMode: 0 30 | SyncSource: lidar 31 | Preferences: 32 | PromptSaveOnExit: true 33 | Toolbars: 34 | toolButtonStyle: 2 35 | Visualization Manager: 36 | Class: "" 37 | Displays: 38 | - Alpha: 0.20000000298023224 39 | Cell Size: 1 40 | Class: rviz/Grid 41 | Color: 160; 160; 164 42 | Enabled: true 43 | Line Style: 44 | Line Width: 0.029999999329447746 45 | Value: Lines 46 | Name: Grid 47 | Normal Cell Count: 0 48 | Offset: 49 | X: 0 50 | Y: 0 51 | Z: 0 52 | Plane: XY 53 | Plane Cell Count: 100 54 | Reference Frame: 55 | Value: true 56 | - Alpha: 0.5 57 | Cell Size: 5 58 | Class: rviz/Grid 59 | Color: 160; 160; 164 60 | Enabled: true 61 | Line Style: 62 | Line Width: 0.029999999329447746 63 | Value: Lines 64 | Name: Grid 65 | Normal Cell Count: 0 66 | Offset: 67 | X: 0 68 | Y: 0 69 | Z: 0 70 | Plane: XY 71 | Plane Cell Count: 100 72 | Reference Frame: 73 | Value: true 74 | - Class: rviz/Group 75 | Displays: 76 | - Angle Tolerance: 0.10000000149011612 77 | Class: rviz/Odometry 78 | Covariance: 79 | Orientation: 80 | Alpha: 0.5 81 | Color: 255; 255; 127 82 | Color Style: Unique 83 | Frame: Local 84 | Offset: 1 85 | Scale: 1 86 | Value: true 87 | Position: 88 | Alpha: 0.30000001192092896 89 | Color: 204; 51; 204 90 | Scale: 1 91 | Value: true 92 | Value: false 93 | Enabled: true 94 | Keep: 1 95 | Name: Odometry 96 | Position Tolerance: 0.10000000149011612 97 | Queue Size: 10 98 | Shape: 99 | Alpha: 1 100 | Axes Length: 1 101 | Axes Radius: 0.10000000149011612 102 | Color: 255; 25; 0 103 | Head Length: 0.30000001192092896 104 | Head Radius: 0.10000000149011612 105 | Shaft Length: 1 106 | Shaft Radius: 0.05000000074505806 107 | Value: Axes 108 | Topic: /uav1/estimation_manager/odom_main 109 | Unreliable: false 110 | Value: true 111 | - Alpha: 1 112 | Autocompute Intensity Bounds: true 113 | Autocompute Value Bounds: 114 | Max Value: 1.3021430969238281 115 | Min Value: -1.1509228944778442 116 | Value: true 117 | Axis: Z 118 | Channel Name: intensity 119 | Class: rviz/PointCloud2 120 | Color: 255; 255; 255 121 | Color Transformer: AxisColor 122 | Decay Time: 0 123 | Enabled: true 124 | Invert Rainbow: false 125 | Max Color: 255; 255; 255 126 | Min Color: 0; 0; 0 127 | Name: lidar 128 | Position Transformer: XYZ 129 | Queue Size: 10 130 | Selectable: true 131 | Size (Pixels): 3 132 | Size (m): 0.10000000149011612 133 | Style: Flat Squares 134 | Topic: /uav1/lidar/points 135 | Unreliable: false 136 | Use Fixed Frame: true 137 | Use rainbow: true 138 | Value: true 139 | - Class: rviz/Image 140 | Enabled: true 141 | Image Topic: /uav1/rgb/image_raw 142 | Max Value: 1 143 | Median window: 5 144 | Min Value: 0 145 | Name: rgb 146 | Normalize Range: true 147 | Queue Size: 2 148 | Transport Hint: raw 149 | Unreliable: false 150 | Value: true 151 | Enabled: true 152 | Name: uav1 153 | - Class: rviz/Group 154 | Displays: 155 | - Angle Tolerance: 0.10000000149011612 156 | Class: rviz/Odometry 157 | Covariance: 158 | Orientation: 159 | Alpha: 0.5 160 | Color: 255; 255; 127 161 | Color Style: Unique 162 | Frame: Local 163 | Offset: 1 164 | Scale: 1 165 | Value: true 166 | Position: 167 | Alpha: 0.30000001192092896 168 | Color: 204; 51; 204 169 | Scale: 1 170 | Value: true 171 | Value: false 172 | Enabled: true 173 | Keep: 1 174 | Name: Odometry 175 | Position Tolerance: 0.10000000149011612 176 | Queue Size: 10 177 | Shape: 178 | Alpha: 1 179 | Axes Length: 1 180 | Axes Radius: 0.10000000149011612 181 | Color: 255; 25; 0 182 | Head Length: 0.30000001192092896 183 | Head Radius: 0.10000000149011612 184 | Shaft Length: 1 185 | Shaft Radius: 0.05000000074505806 186 | Value: Axes 187 | Topic: /uav2/estimation_manager/odom_main 188 | Unreliable: false 189 | Value: true 190 | - Alpha: 1 191 | Autocompute Intensity Bounds: true 192 | Autocompute Value Bounds: 193 | Max Value: 0.9032437801361084 194 | Min Value: -1.1521259546279907 195 | Value: true 196 | Axis: Z 197 | Channel Name: intensity 198 | Class: rviz/PointCloud2 199 | Color: 255; 255; 255 200 | Color Transformer: AxisColor 201 | Decay Time: 0 202 | Enabled: true 203 | Invert Rainbow: false 204 | Max Color: 255; 255; 255 205 | Min Color: 0; 0; 0 206 | Name: lidar 207 | Position Transformer: XYZ 208 | Queue Size: 10 209 | Selectable: true 210 | Size (Pixels): 3 211 | Size (m): 0.10000000149011612 212 | Style: Flat Squares 213 | Topic: /uav2/lidar/points 214 | Unreliable: false 215 | Use Fixed Frame: true 216 | Use rainbow: true 217 | Value: true 218 | - Class: rviz/Image 219 | Enabled: true 220 | Image Topic: /uav2/rgb/image_raw 221 | Max Value: 1 222 | Median window: 5 223 | Min Value: 0 224 | Name: rgb 225 | Normalize Range: true 226 | Queue Size: 2 227 | Transport Hint: raw 228 | Unreliable: false 229 | Value: true 230 | Enabled: true 231 | Name: uav2 232 | Enabled: true 233 | Global Options: 234 | Background Color: 255; 255; 255 235 | Default Light: true 236 | Fixed Frame: uav1/world_origin 237 | Frame Rate: 60 238 | Name: root 239 | Tools: 240 | - Class: rviz/Interact 241 | Hide Inactive Objects: true 242 | - Class: rviz/MoveCamera 243 | - Class: rviz/Select 244 | - Class: rviz/FocusCamera 245 | - Class: rviz/Measure 246 | - Class: rviz/SetInitialPose 247 | Theta std deviation: 0.2617993950843811 248 | Topic: /initialpose 249 | X std deviation: 0.5 250 | Y std deviation: 0.5 251 | - Class: rviz/SetGoal 252 | Topic: /move_base_simple/goal 253 | - Class: rviz/PublishPoint 254 | Single click: true 255 | Topic: /clicked_point 256 | - Class: mrs_rviz_plugins/ControlTool 257 | - Class: mrs_rviz_plugins/WaypointPlanner 258 | Drone name: uav1 259 | Fly now: true 260 | Height offset: 0 261 | Loop: false 262 | Shape: Axes 263 | Stop at waypoints: false 264 | Topic: trajectory_generation/path 265 | Use heading: true 266 | - Class: mrs_rviz_plugins/NamedSetGoal 267 | Name: name 268 | Topic: goal 269 | Value: true 270 | Views: 271 | Current: 272 | Class: rviz/Orbit 273 | Distance: 12.6915922164917 274 | Enable Stereo Rendering: 275 | Stereo Eye Separation: 0.05999999865889549 276 | Stereo Focal Distance: 1 277 | Swap Stereo Eyes: false 278 | Value: false 279 | Field of View: 0.7853981852531433 280 | Focal Point: 281 | X: 0.2424663007259369 282 | Y: 1.8529112339019775 283 | Z: 0.26631325483322144 284 | Focal Shape Fixed Size: true 285 | Focal Shape Size: 0.05000000074505806 286 | Invert Z Axis: false 287 | Name: Current View 288 | Near Clip Distance: 0.009999999776482582 289 | Pitch: 0.5053986310958862 290 | Target Frame: uav1/fcu 291 | Yaw: 2.2454402446746826 292 | Saved: ~ 293 | Window Geometry: 294 | Displays: 295 | collapsed: false 296 | Height: 1060 297 | Hide Left Dock: false 298 | Hide Right Dock: true 299 | QMainWindow State: 000000ff00000000fd00000004000000000000022a000003cefc020000000dfb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003b000001f2000000c700fffffffb0000001400760069006f005f00630061006d0065007200610000000122000000bd0000000000000000fb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d00610067006500000003a1000001930000000000000000fb0000001400760069006f005f00630061006d00650072006100000001400000009f0000000000000000fb0000000a0049006d0061006700650100000196000000fd0000000000000000fb000000060072006700620100000233000000e50000001600fffffffb00000006007200670062010000031e000000eb0000001600ffffff0000000100000116000001a4fc0200000004fb0000001e0054006f006f006c002000500072006f0070006500720074006900650073000000003b000000e40000005c00fffffffb0000000a005600690065007700730000000125000000ba000000a000fffffffb0000001e0054006f006f006c002000500072006f0070006500720074006900650073000000016d0000016e0000000000000000fb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000038f0000003efc0100000002fb0000000800540069006d006500000000000000038f0000035c00fffffffb0000000800540069006d00650100000000000004500000000000000000000003f8000003ce00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 300 | Selection: 301 | collapsed: false 302 | Time: 303 | collapsed: false 304 | Tool Properties: 305 | collapsed: true 306 | Views: 307 | collapsed: true 308 | Width: 1576 309 | X: 2361 310 | Y: 96 311 | rgb: 312 | collapsed: false 313 | -------------------------------------------------------------------------------- /tmux/two_drones/session.yml: -------------------------------------------------------------------------------- 1 | # do not modify these 2 | root: ./ 3 | name: simulation 4 | socket_name: mrs 5 | attach: false 6 | tmux_options: -f /etc/ctu-mrs/tmux.conf 7 | # you can modify these 8 | pre_window: export UAV_NAME=uav1; export RUN_TYPE=simulation; export UAV_TYPE=x500 9 | startup_window: goto 10 | windows: 11 | - roscore: 12 | layout: tiled 13 | panes: 14 | - roscore 15 | - simulator: 16 | layout: tiled 17 | panes: 18 | - waitForRos; roslaunch mrs_uav_unreal_simulation unreal_simulator.launch custom_config:=./config/simulator.yaml 19 | - hw_api: 20 | layout: tiled 21 | panes: 22 | - export UAV_NAME=uav1; waitForTime; roslaunch mrs_uav_unreal_simulation hw_api.launch 23 | - export UAV_NAME=uav2; waitForTime; roslaunch mrs_uav_unreal_simulation hw_api.launch 24 | - takeoff: 25 | layout: tiled 26 | panes: 27 | - export UAV_NAME=uav1; waitForHw; roslaunch mrs_uav_autostart automatic_start.launch 28 | - export UAV_NAME=uav1; waitForControl; rosservice call /$UAV_NAME/hw_api/arming 1; sleep 2; rosservice call /$UAV_NAME/hw_api/offboard 29 | - export UAV_NAME=uav2; waitForHw; roslaunch mrs_uav_autostart automatic_start.launch 30 | - export UAV_NAME=uav2; waitForControl; rosservice call /$UAV_NAME/hw_api/arming 1; sleep 2; rosservice call /$UAV_NAME/hw_api/offboard 31 | # - waitForControl; rosservice call /$UAV_NAME/hw_api/arming 1; rosservice call /$UAV_NAME/uav_manager/midair_activation 32 | - status: 33 | layout: tiled 34 | panes: 35 | - export UAV_NAME=uav1; waitForHw; roslaunch mrs_uav_status status.launch 36 | - export UAV_NAME=uav2; waitForHw; roslaunch mrs_uav_status status.launch 37 | - control: 38 | layout: tiled 39 | panes: 40 | - export UAV_NAME=uav1; waitForHw; sleep 3; roslaunch mrs_uav_core core.launch 41 | platform_config:=`rospack find mrs_multirotor_simulator`/config/mrs_uav_system/$UAV_TYPE.yaml 42 | custom_config:=./config/custom_config.yaml 43 | world_config:=./config/world_config.yaml 44 | network_config:=./config/network_config.yaml 45 | - export UAV_NAME=uav2; waitForHw; sleep 3; roslaunch mrs_uav_core core.launch 46 | platform_config:=`rospack find mrs_multirotor_simulator`/config/mrs_uav_system/$UAV_TYPE.yaml 47 | custom_config:=./config/custom_config.yaml 48 | world_config:=./config/world_config.yaml 49 | network_config:=./config/network_config.yaml 50 | 51 | - rviz: 52 | layout: tiled 53 | panes: 54 | - waitForControl; rosrun rviz rviz -d ./rviz.rviz 55 | - waitForControl; roslaunch mrs_rviz_plugins load_robot.launch 56 | - waitForControl; waitForControl; roslaunch mrs_rviz_plugins rviz_interface.launch 57 | - tf_connector: 58 | layout: tiled 59 | panes: 60 | - waitForRos; roslaunch mrs_tf_connector tf_connector.launch 61 | 62 | - layout: 63 | layout: tiled 64 | panes: 65 | - waitForControl; sleep 5; ~/.i3/layout_manager.sh ./layout.json 66 | -------------------------------------------------------------------------------- /tmux/two_drones/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Absolute path to this script. /home/user/bin/foo.sh 4 | SCRIPT=$(readlink -f $0) 5 | # Absolute path this script is in. /home/user/bin 6 | SCRIPTPATH=`dirname $SCRIPT` 7 | cd "$SCRIPTPATH" 8 | 9 | export TMUX_SESSION_NAME=simulation 10 | export TMUX_SOCKET_NAME=mrs 11 | 12 | # start tmuxinator 13 | tmuxinator start -p ./session.yml 14 | 15 | # if we are not in tmux 16 | if [ -z $TMUX ]; then 17 | 18 | # just attach to the session 19 | tmux -L $TMUX_SOCKET_NAME a -t $TMUX_SESSION_NAME 20 | 21 | # if we are in tmux 22 | else 23 | 24 | # switch to the newly-started session 25 | tmux detach-client -E "tmux -L $TMUX_SOCKET_NAME a -t $TMUX_SESSION_NAME" 26 | 27 | fi 28 | --------------------------------------------------------------------------------