Compare commits
183 Commits
beacons
...
send_setpo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c219359487 | ||
|
|
ea4cfb17ec | ||
|
|
8efa23948d | ||
|
|
a919c5b7f7 | ||
|
|
8be8a6d1f3 | ||
|
|
a24c145968 | ||
|
|
baad3abae2 | ||
|
|
0b98dfbf02 | ||
|
|
4846ee5052 | ||
|
|
22126929a7 | ||
|
|
d74b7db6b3 | ||
|
|
8f7e496107 | ||
|
|
de2af0cf7c | ||
|
|
9abee2b965 | ||
|
|
f4819381a5 | ||
|
|
1ff1218359 | ||
|
|
1c995253bd | ||
|
|
8f807bdfa3 | ||
|
|
b9b8c99f20 | ||
|
|
6129216d80 | ||
|
|
5996ac225a | ||
|
|
e7582c5760 | ||
|
|
db2b25e60d | ||
|
|
fb34e50b38 | ||
|
|
d82b1925a4 | ||
|
|
3e740de48e | ||
|
|
c7dd7a25a0 | ||
|
|
65cd11ca11 | ||
|
|
eeb67733d3 | ||
|
|
568197a95a | ||
|
|
500356f4e9 | ||
|
|
7b0520c920 | ||
|
|
3f2ffd6dc7 | ||
|
|
04cad041b6 | ||
|
|
ac759ace13 | ||
|
|
a739fb51c3 | ||
|
|
a9c63cc235 | ||
|
|
e0c9c2601d | ||
|
|
6348e5371f | ||
|
|
4eb876df0c | ||
|
|
9c3dcb463d | ||
|
|
048a1b4929 | ||
|
|
346e41f475 | ||
|
|
33d173d1e0 | ||
|
|
088af872f9 | ||
|
|
60033323d4 | ||
|
|
6b33ded940 | ||
|
|
ae18d7834a | ||
|
|
4449c6cc1f | ||
|
|
23a59a449c | ||
|
|
3fe7b60374 | ||
|
|
19d1987484 | ||
|
|
c0d327165c | ||
|
|
799ef4237e | ||
|
|
0c543614a9 | ||
|
|
c4e9e3bb10 | ||
|
|
37b5f14f72 | ||
|
|
1515206e2e | ||
|
|
52f237fcb5 | ||
|
|
a037b7f00e | ||
|
|
b775f8015c | ||
|
|
10c0b5ae5f | ||
|
|
4b063ce9b2 | ||
|
|
f767ee2583 | ||
|
|
1224735954 | ||
|
|
a3b0b761e7 | ||
|
|
806317a04c | ||
|
|
b03951faab | ||
|
|
5b935af894 | ||
|
|
7545a8a2a8 | ||
|
|
9464dbf5ac | ||
|
|
c9f546cb0c | ||
|
|
f883d826ec | ||
|
|
5a7a54fc53 | ||
|
|
7a2f19d311 | ||
|
|
b8f572d86f | ||
|
|
c8a61cac40 | ||
|
|
52132684d2 | ||
|
|
8acd7f2c73 | ||
|
|
b4494a726d | ||
|
|
c44dcb7f89 | ||
|
|
29931565e2 | ||
|
|
abd5931461 | ||
|
|
7fa1cd5816 | ||
|
|
1775cae443 | ||
|
|
d24f91512f | ||
|
|
bd8cec8516 | ||
|
|
388963511a | ||
|
|
e3466a1077 | ||
|
|
0107bb3c0b | ||
|
|
6bdb10dd5c | ||
|
|
5496e400cf | ||
|
|
4ed6dde80e | ||
|
|
78ac1963df | ||
|
|
fd2ace29ce | ||
|
|
455c495685 | ||
|
|
4540a24d85 | ||
|
|
a12d1836fe | ||
|
|
43f3838979 | ||
|
|
5b6c097bd9 | ||
|
|
b5daa4a77a | ||
|
|
15e530067e | ||
|
|
8b1790f763 | ||
|
|
010559ea9b | ||
|
|
9ace6a70b3 | ||
|
|
5ea8d5674f | ||
|
|
f53385ae0a | ||
|
|
c748bc5da8 | ||
|
|
5c4d47b590 | ||
|
|
0d52a66d2a | ||
|
|
40facd933b | ||
|
|
59421316b4 | ||
|
|
078a4a1a1a | ||
|
|
39ca39e983 | ||
|
|
9af542d4ad | ||
|
|
48b5016897 | ||
|
|
09cda4e1d0 | ||
|
|
8aa5e6fe35 | ||
|
|
8fb86a5e2d | ||
|
|
ed542e2f21 | ||
|
|
df18c9bba6 | ||
|
|
1c1ea30dc0 | ||
|
|
b258131480 | ||
|
|
5f98cb2f10 | ||
|
|
8cbf27cd63 | ||
|
|
85390c0d4d | ||
|
|
6da45f1240 | ||
|
|
9942e65bd3 | ||
|
|
0c944ce3b6 | ||
|
|
2103260f0f | ||
|
|
1fc71c7ca7 | ||
|
|
8fd8662e0d | ||
|
|
e8ecc7eac4 | ||
|
|
fd83eb616a | ||
|
|
3110abcbf0 | ||
|
|
076bb6507b | ||
|
|
de9510c096 | ||
|
|
32d73ba229 | ||
|
|
91354beb0b | ||
|
|
a1b778b74b | ||
|
|
be267f2aff | ||
|
|
615d026eb6 | ||
|
|
263f1c154e | ||
|
|
68cb8effa9 | ||
|
|
a444ce3193 | ||
|
|
091fe9a4ee | ||
|
|
988c546f15 | ||
|
|
225c9ef7ae | ||
|
|
16192c6c8b | ||
|
|
cedff67864 | ||
|
|
682b18d396 | ||
|
|
38a34a6de7 | ||
|
|
1ac0bfead3 | ||
|
|
8712315b92 | ||
|
|
7ae5295134 | ||
|
|
bec6025654 | ||
|
|
4d4647f348 | ||
|
|
98668938cc | ||
|
|
99b34fa55e | ||
|
|
f3e4468339 | ||
|
|
645754e56f | ||
|
|
200f1f97ec | ||
|
|
1c3ab27707 | ||
|
|
4e8e1c8177 | ||
|
|
0f0324ab9d | ||
|
|
126ff49a35 | ||
|
|
345e796392 | ||
|
|
e5ddab280e | ||
|
|
9e5f2363f6 | ||
|
|
4f530da21d | ||
|
|
1df349b478 | ||
|
|
24fc0c2ca5 | ||
|
|
31503b8b70 | ||
|
|
a6fd08738c | ||
|
|
b88d8beb39 | ||
|
|
4df0d69b53 | ||
|
|
ed71dfb0e9 | ||
|
|
353bf74930 | ||
|
|
015d7d7596 | ||
|
|
f0f63b1817 | ||
|
|
eaeb2dba5a | ||
|
|
ee2d5c4d54 | ||
|
|
5ce3d43841 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
|
.vscode/
|
||||||
build/
|
build/
|
||||||
install/
|
install/
|
||||||
log/
|
log/
|
||||||
|
|||||||
4
.vscode/c_cpp_properties.json
vendored
4
.vscode/c_cpp_properties.json
vendored
@@ -10,7 +10,9 @@
|
|||||||
"/home/ubuntu/ros2_ws/src/beacon_positioning/include/**",
|
"/home/ubuntu/ros2_ws/src/beacon_positioning/include/**",
|
||||||
"/usr/include/**",
|
"/usr/include/**",
|
||||||
"/mnt/Homework/Avans/AFSTUDEERSTAGE/positioning_systems_api/rtls_driver/include/**",
|
"/mnt/Homework/Avans/AFSTUDEERSTAGE/positioning_systems_api/rtls_driver/include/**",
|
||||||
"/mnt/Homework/Avans/AFSTUDEERSTAGE/positioning_systems_api/serial_communication/include/**"
|
"/mnt/Homework/Avans/AFSTUDEERSTAGE/positioning_systems_api/serial_communication/include/**",
|
||||||
|
"/mnt/Homework/Avans/AFSTUDEERSTAGE/terabee_api/include/**",
|
||||||
|
"/home/ubuntu/ros2_ws/build/px4_msgs/rosidl_generator_cpp/px4_msgs/msg/**"
|
||||||
],
|
],
|
||||||
"name": "ROS",
|
"name": "ROS",
|
||||||
"intelliSenseMode": "gcc-x64",
|
"intelliSenseMode": "gcc-x64",
|
||||||
|
|||||||
61
.vscode/settings.json
vendored
61
.vscode/settings.json
vendored
@@ -1,7 +1,66 @@
|
|||||||
{
|
{
|
||||||
"ros.distro": "humble",
|
"ros.distro": "humble",
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"chrono": "cpp"
|
"chrono": "cpp",
|
||||||
|
"array": "cpp",
|
||||||
|
"atomic": "cpp",
|
||||||
|
"bit": "cpp",
|
||||||
|
"*.tcc": "cpp",
|
||||||
|
"cctype": "cpp",
|
||||||
|
"clocale": "cpp",
|
||||||
|
"cmath": "cpp",
|
||||||
|
"codecvt": "cpp",
|
||||||
|
"compare": "cpp",
|
||||||
|
"concepts": "cpp",
|
||||||
|
"condition_variable": "cpp",
|
||||||
|
"csignal": "cpp",
|
||||||
|
"cstdint": "cpp",
|
||||||
|
"cstdio": "cpp",
|
||||||
|
"cstdlib": "cpp",
|
||||||
|
"cstring": "cpp",
|
||||||
|
"ctime": "cpp",
|
||||||
|
"cwchar": "cpp",
|
||||||
|
"cwctype": "cpp",
|
||||||
|
"deque": "cpp",
|
||||||
|
"list": "cpp",
|
||||||
|
"map": "cpp",
|
||||||
|
"set": "cpp",
|
||||||
|
"unordered_map": "cpp",
|
||||||
|
"unordered_set": "cpp",
|
||||||
|
"vector": "cpp",
|
||||||
|
"exception": "cpp",
|
||||||
|
"functional": "cpp",
|
||||||
|
"future": "cpp",
|
||||||
|
"initializer_list": "cpp",
|
||||||
|
"iomanip": "cpp",
|
||||||
|
"iosfwd": "cpp",
|
||||||
|
"iostream": "cpp",
|
||||||
|
"istream": "cpp",
|
||||||
|
"limits": "cpp",
|
||||||
|
"memory": "cpp",
|
||||||
|
"mutex": "cpp",
|
||||||
|
"new": "cpp",
|
||||||
|
"numbers": "cpp",
|
||||||
|
"numeric": "cpp",
|
||||||
|
"optional": "cpp",
|
||||||
|
"ostream": "cpp",
|
||||||
|
"ratio": "cpp",
|
||||||
|
"semaphore": "cpp",
|
||||||
|
"shared_mutex": "cpp",
|
||||||
|
"sstream": "cpp",
|
||||||
|
"stdexcept": "cpp",
|
||||||
|
"stop_token": "cpp",
|
||||||
|
"streambuf": "cpp",
|
||||||
|
"string": "cpp",
|
||||||
|
"string_view": "cpp",
|
||||||
|
"system_error": "cpp",
|
||||||
|
"thread": "cpp",
|
||||||
|
"type_traits": "cpp",
|
||||||
|
"tuple": "cpp",
|
||||||
|
"typeindex": "cpp",
|
||||||
|
"typeinfo": "cpp",
|
||||||
|
"utility": "cpp",
|
||||||
|
"variant": "cpp"
|
||||||
},
|
},
|
||||||
"python.autoComplete.extraPaths": [
|
"python.autoComplete.extraPaths": [
|
||||||
"/home/ubuntu/ros2_ws/install/px4_msgs/lib/python3.8/site-packages",
|
"/home/ubuntu/ros2_ws/install/px4_msgs/lib/python3.8/site-packages",
|
||||||
|
|||||||
0
TerabeeLog.log
Normal file
0
TerabeeLog.log
Normal file
7
get_build.sh
Executable file
7
get_build.sh
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
echo "updating git..."
|
||||||
|
./fgit.sh
|
||||||
|
echo "building package..."
|
||||||
|
colcon build --packages-select px4_connection
|
||||||
|
#echo "launching controller..."
|
||||||
|
#ros2 run px4_connection px4_controller
|
||||||
BIN
mav.tlog.raw
Normal file
BIN
mav.tlog.raw
Normal file
Binary file not shown.
1120
script_outputs/microxrcedds.log
Normal file
1120
script_outputs/microxrcedds.log
Normal file
File diff suppressed because it is too large
Load Diff
5474
script_outputs/script-output-25-05-1123.txt
Normal file
5474
script_outputs/script-output-25-05-1123.txt
Normal file
File diff suppressed because one or more lines are too long
@@ -31,7 +31,9 @@ rosidl_generate_interfaces(${PROJECT_NAME}
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_executable(tracker_position src/tracker_position.cpp)
|
add_executable(tracker_position src/tracker_position.cpp)
|
||||||
ament_target_dependencies(tracker_position rclcpp std_msgs beacon_positioning)
|
ament_target_dependencies(tracker_position rclcpp std_msgs
|
||||||
|
beacon_positioning
|
||||||
|
)
|
||||||
|
|
||||||
target_link_libraries(tracker_position
|
target_link_libraries(tracker_position
|
||||||
positioning_systems_api::serial_communication
|
positioning_systems_api::serial_communication
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ int main(int argc, char **argv)
|
|||||||
if (tracker_msg.is_valid_position)
|
if (tracker_msg.is_valid_position)
|
||||||
{
|
{
|
||||||
RCLCPP_INFO(node->get_logger(), "x = %f, y = %f, z = %f", tracker_msg.tracker_position_xyz.at(0), tracker_msg.tracker_position_xyz.at(1), tracker_msg.tracker_position_xyz.at(2));
|
RCLCPP_INFO(node->get_logger(), "x = %f, y = %f, z = %f", tracker_msg.tracker_position_xyz.at(0), tracker_msg.tracker_position_xyz.at(1), tracker_msg.tracker_position_xyz.at(2));
|
||||||
for (int i = 0; i < tracker_msg.anchors_data.size(); i++)
|
for (size_t i = 0; i < tracker_msg.anchors_data.size(); i++)
|
||||||
{
|
{
|
||||||
RCLCPP_INFO(node->get_logger(), "anchor number= %d, distance = %d, x = %d, y = %d, z = %d", tracker_msg.anchors_data[i].number, tracker_msg.anchors_data[i].distance, tracker_msg.anchors_data[i].pos_x, tracker_msg.anchors_data[i].pos_y, tracker_msg.anchors_data[i].pos_z);
|
RCLCPP_INFO(node->get_logger(), "anchor number= %d, distance = %d, x = %d, y = %d, z = %d", tracker_msg.anchors_data[i].number, tracker_msg.anchors_data[i].distance, tracker_msg.anchors_data[i].pos_x, tracker_msg.anchors_data[i].pos_y, tracker_msg.anchors_data[i].pos_z);
|
||||||
}
|
}
|
||||||
@@ -160,7 +160,7 @@ int main(int argc, char **argv)
|
|||||||
message.y_pos = tracker_msg.tracker_position_xyz.at(1);
|
message.y_pos = tracker_msg.tracker_position_xyz.at(1);
|
||||||
message.z_pos = tracker_msg.tracker_position_xyz.at(2);
|
message.z_pos = tracker_msg.tracker_position_xyz.at(2);
|
||||||
message.anchor_distances = {0, 0, 0, 0};
|
message.anchor_distances = {0, 0, 0, 0};
|
||||||
for (int i = 0; i < tracker_msg.anchors_data.size(); i++)
|
for (size_t i = 0; i < tracker_msg.anchors_data.size(); i++)
|
||||||
{
|
{
|
||||||
message.anchor_distances[i] = tracker_msg.anchors_data[i].distance;
|
message.anchor_distances[i] = tracker_msg.anchors_data[i].distance;
|
||||||
}
|
}
|
||||||
|
|||||||
33
src/drone_controls/CMakeLists.txt
Normal file
33
src/drone_controls/CMakeLists.txt
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
project(drone_controls)
|
||||||
|
|
||||||
|
# Default to C99
|
||||||
|
if(NOT CMAKE_C_STANDARD)
|
||||||
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Default to C++14
|
||||||
|
if(NOT CMAKE_CXX_STANDARD)
|
||||||
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
|
add_compile_options(-Wall -Wextra -Wpedantic)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# find dependencies
|
||||||
|
find_package(ament_cmake REQUIRED)
|
||||||
|
find_package(rclcpp REQUIRED)
|
||||||
|
|
||||||
|
if(BUILD_TESTING)
|
||||||
|
find_package(ament_lint_auto REQUIRED)
|
||||||
|
# the following line skips the linter which checks for copyrights
|
||||||
|
# uncomment the line when a copyright and license is not present in all source files
|
||||||
|
#set(ament_cmake_copyright_FOUND TRUE)
|
||||||
|
# the following line skips cpplint (only works in a git repo)
|
||||||
|
# uncomment the line when this package is not in a git repo
|
||||||
|
#set(ament_cmake_cpplint_FOUND TRUE)
|
||||||
|
ament_lint_auto_find_test_dependencies()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
ament_package()
|
||||||
20
src/drone_controls/package.xml
Normal file
20
src/drone_controls/package.xml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||||
|
<package format="3">
|
||||||
|
<name>drone_controls</name>
|
||||||
|
<version>0.0.0</version>
|
||||||
|
<description>TODO: Package description</description>
|
||||||
|
<maintainer email="ubuntu@todo.todo">ubuntu</maintainer>
|
||||||
|
<license>TODO: License declaration</license>
|
||||||
|
|
||||||
|
<buildtool_depend>ament_cmake</buildtool_depend>
|
||||||
|
|
||||||
|
<depend>rclcpp</depend>
|
||||||
|
|
||||||
|
<test_depend>ament_lint_auto</test_depend>
|
||||||
|
<test_depend>ament_lint_common</test_depend>
|
||||||
|
|
||||||
|
<export>
|
||||||
|
<build_type>ament_cmake</build_type>
|
||||||
|
</export>
|
||||||
|
</package>
|
||||||
58
src/height/CMakeLists.txt
Normal file
58
src/height/CMakeLists.txt
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
project(height)
|
||||||
|
|
||||||
|
# Default to C99
|
||||||
|
if(NOT CMAKE_C_STANDARD)
|
||||||
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Default to C++14
|
||||||
|
if(NOT CMAKE_CXX_STANDARD)
|
||||||
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
|
add_compile_options(-Wall -Wextra -Wpedantic)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# find dependencies
|
||||||
|
find_package(ament_cmake REQUIRED)
|
||||||
|
find_package(rclcpp REQUIRED)
|
||||||
|
find_package(TerabeeApi REQUIRED)
|
||||||
|
find_package(rosidl_default_generators REQUIRED)
|
||||||
|
find_package(height REQUIRED)
|
||||||
|
|
||||||
|
rosidl_generate_interfaces(${PROJECT_NAME}
|
||||||
|
"msg/HeightData.msg"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(height_reader src/height_reader.cpp)
|
||||||
|
target_include_directories(height_reader PUBLIC
|
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||||
|
$<INSTALL_INTERFACE:include>)
|
||||||
|
|
||||||
|
target_link_libraries(height_reader ${TerabeeApi_LIBRARIES})
|
||||||
|
target_include_directories(height_reader PUBLIC ${TerabeeApi_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
ament_target_dependencies(
|
||||||
|
height_reader
|
||||||
|
rclcpp
|
||||||
|
TerabeeApi
|
||||||
|
height
|
||||||
|
)
|
||||||
|
|
||||||
|
install(TARGETS height_reader
|
||||||
|
DESTINATION lib/${PROJECT_NAME})
|
||||||
|
|
||||||
|
if(BUILD_TESTING)
|
||||||
|
find_package(ament_lint_auto REQUIRED)
|
||||||
|
# the following line skips the linter which checks for copyrights
|
||||||
|
# uncomment the line when a copyright and license is not present in all source files
|
||||||
|
#set(ament_cmake_copyright_FOUND TRUE)
|
||||||
|
# the following line skips cpplint (only works in a git repo)
|
||||||
|
# uncomment the line when this package is not in a git repo
|
||||||
|
#set(ament_cmake_cpplint_FOUND TRUE)
|
||||||
|
ament_lint_auto_find_test_dependencies()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
ament_package()
|
||||||
2
src/height/msg/HeightData.msg
Normal file
2
src/height/msg/HeightData.msg
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
float32[4] heights
|
||||||
|
float32 min_height
|
||||||
27
src/height/package.xml
Normal file
27
src/height/package.xml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||||
|
<package format="3">
|
||||||
|
<name>height</name>
|
||||||
|
<version>0.0.0</version>
|
||||||
|
<description>package to read Terabee node</description>
|
||||||
|
<maintainer email="semmer99@gmail.com">ubuntu</maintainer>
|
||||||
|
<license>Apache License 2.0</license>
|
||||||
|
|
||||||
|
<buildtool_depend>ament_cmake</buildtool_depend>
|
||||||
|
<build_depend>rosidl_default_generators</build_depend>
|
||||||
|
<exec_depend>rosidl_default_runtime</exec_depend>
|
||||||
|
<member_of_group>rosidl_interface_packages</member_of_group>
|
||||||
|
|
||||||
|
<depend>rclcpp</depend>
|
||||||
|
|
||||||
|
<test_depend>ament_lint_auto</test_depend>
|
||||||
|
<test_depend>ament_lint_common</test_depend>
|
||||||
|
|
||||||
|
<build_depend>TerabeeApi</build_depend>
|
||||||
|
<exec_depend>TerabeeApi</exec_depend>
|
||||||
|
|
||||||
|
|
||||||
|
<export>
|
||||||
|
<build_type>ament_cmake</build_type>
|
||||||
|
</export>
|
||||||
|
</package>
|
||||||
97
src/height/src/height_reader.cpp
Normal file
97
src/height/src/height_reader.cpp
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "rclcpp/rclcpp.hpp"
|
||||||
|
#include "height/msg/height_data.hpp"
|
||||||
|
|
||||||
|
#include <terabee/ITerarangerFactory.hpp>
|
||||||
|
#include <terabee/ITerarangerEvoMini.hpp>
|
||||||
|
#include <terabee/DistanceData.hpp>
|
||||||
|
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
|
using terabee::DistanceData;
|
||||||
|
using terabee::ITerarangerEvoMini;
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &os, const DistanceData &d)
|
||||||
|
{
|
||||||
|
os << "[";
|
||||||
|
for (size_t i = 0; i < d.distance.size(); i++)
|
||||||
|
{
|
||||||
|
os << d.distance[i] << ", ";
|
||||||
|
}
|
||||||
|
os << "\b\b"
|
||||||
|
<< " ]";
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
class HeightReader : public rclcpp::Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HeightReader() : rclcpp::Node("height_reader")
|
||||||
|
{
|
||||||
|
rcl_interfaces::msg::ParameterDescriptor descriptor = rcl_interfaces::msg::ParameterDescriptor{};
|
||||||
|
descriptor.description = "serial port for the USB port of the height sensor";
|
||||||
|
|
||||||
|
this->declare_parameter("height_serial_port", "/dev/ttyACM0", descriptor);
|
||||||
|
|
||||||
|
factory = terabee::ITerarangerFactory::getFactory();
|
||||||
|
evo_mini = factory->createTerarangerEvoMini(this->get_parameter("height_serial_port").as_string());
|
||||||
|
|
||||||
|
if (!evo_mini)
|
||||||
|
{
|
||||||
|
RCLCPP_ERROR(this->get_logger(), "Failed to create Evo Mini!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
evo_mini->setPixelMode(ITerarangerEvoMini::Px4Mode);
|
||||||
|
|
||||||
|
if (!evo_mini->initialize())
|
||||||
|
{
|
||||||
|
RCLCPP_ERROR(this->get_logger(), "Failed to initialize evo mini!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RCLCPP_INFO(this->get_logger(), "Succesfully initialized Evo mini!");
|
||||||
|
|
||||||
|
timer_ = this->create_wall_timer(500ms, std::bind(&HeightReader::read_height, this));
|
||||||
|
publisher_ = this->create_publisher<height::msg::HeightData>("drone/height", 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void read_height()
|
||||||
|
{
|
||||||
|
auto msg = height::msg::HeightData();
|
||||||
|
|
||||||
|
float min = 255;
|
||||||
|
terabee::DistanceData distance_data = evo_mini->getDistance();
|
||||||
|
for (size_t i = 0; i < distance_data.size(); i++)
|
||||||
|
{
|
||||||
|
msg.heights[i] = distance_data.distance[i];
|
||||||
|
if (distance_data.distance[i] < min && distance_data.distance[i] >= 0)
|
||||||
|
{
|
||||||
|
min = distance_data.distance[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg.min_height = min;
|
||||||
|
publisher_->publish(msg);
|
||||||
|
|
||||||
|
RCLCPP_INFO(this->get_logger(),"publishing message with min distance %f",msg.min_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
rclcpp::TimerBase::SharedPtr timer_;
|
||||||
|
rclcpp::Publisher<height::msg::HeightData>::SharedPtr publisher_;
|
||||||
|
|
||||||
|
std::unique_ptr<terabee::ITerarangerFactory> factory;
|
||||||
|
std::unique_ptr<terabee::ITerarangerEvoMini> evo_mini;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
|
||||||
|
rclcpp::init(argc, argv);
|
||||||
|
rclcpp::spin(std::make_shared<HeightReader>());
|
||||||
|
rclcpp::shutdown();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
71
src/object_detection/CMakeLists.txt
Normal file
71
src/object_detection/CMakeLists.txt
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
project(object_detection)
|
||||||
|
|
||||||
|
# Default to C99
|
||||||
|
if(NOT CMAKE_C_STANDARD)
|
||||||
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Default to C++14
|
||||||
|
if(NOT CMAKE_CXX_STANDARD)
|
||||||
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
|
add_compile_options(-Wall -Wextra -Wpedantic)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# find dependencies
|
||||||
|
find_package(ament_cmake REQUIRED)
|
||||||
|
# uncomment the following section in order to fill in
|
||||||
|
# further dependencies manually.
|
||||||
|
# find_package(<dependency> REQUIRED)
|
||||||
|
find_package(rclcpp REQUIRED)
|
||||||
|
find_package(TerabeeApi REQUIRED)
|
||||||
|
find_package(rosidl_default_generators REQUIRED)
|
||||||
|
find_package(object_detection REQUIRED)
|
||||||
|
|
||||||
|
rosidl_generate_interfaces(${PROJECT_NAME}
|
||||||
|
"msg/LidarReading.msg"
|
||||||
|
"msg/MultiflexReading.msg"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(lidar_reader src/lidar_reader.cpp)
|
||||||
|
ament_target_dependencies(lidar_reader rclcpp
|
||||||
|
object_detection
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(lidar_reader ${TerabeeApi_LIBRARIES})
|
||||||
|
target_include_directories(lidar_reader PUBLIC ${TerabeeApi_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
add_executable(multiflex_reader src/multiflex_reader.cpp)
|
||||||
|
ament_target_dependencies(multiflex_reader rclcpp
|
||||||
|
object_detection
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(multiflex_reader ${TerabeeApi_LIBRARIES})
|
||||||
|
target_include_directories(multiflex_reader PUBLIC ${TerabeeApi_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
install(TARGETS
|
||||||
|
lidar_reader
|
||||||
|
multiflex_reader
|
||||||
|
DESTINATION lib/${PROJECT_NAME}
|
||||||
|
)
|
||||||
|
|
||||||
|
install(
|
||||||
|
DIRECTORY launch
|
||||||
|
DESTINATION share/${PROJECT_NAME}
|
||||||
|
)
|
||||||
|
|
||||||
|
if(BUILD_TESTING)
|
||||||
|
find_package(ament_lint_auto REQUIRED)
|
||||||
|
# the following line skips the linter which checks for copyrights
|
||||||
|
# uncomment the line when a copyright and license is not present in all source files
|
||||||
|
#set(ament_cmake_copyright_FOUND TRUE)
|
||||||
|
# the following line skips cpplint (only works in a git repo)
|
||||||
|
# uncomment the line when this package is not in a git repo
|
||||||
|
#set(ament_cmake_cpplint_FOUND TRUE)
|
||||||
|
ament_lint_auto_find_test_dependencies()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
ament_package()
|
||||||
23
src/object_detection/launch/object_detection_launch_both.py
Normal file
23
src/object_detection/launch/object_detection_launch_both.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
from launch import LaunchDescription
|
||||||
|
from launch_ros.actions import Node
|
||||||
|
|
||||||
|
def generate_launch_description():
|
||||||
|
return LaunchDescription([
|
||||||
|
Node(
|
||||||
|
package="object_detection",
|
||||||
|
executable="multiflex_reader",
|
||||||
|
name="multiflex_reader",
|
||||||
|
parameters=[
|
||||||
|
{"multiflex_serial_port": "/dev/ttyACM0"}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
Node(
|
||||||
|
package="object_detection",
|
||||||
|
executable="lidar_reader",
|
||||||
|
name="lidar_reader",
|
||||||
|
parameters=[
|
||||||
|
{"lidar_serial_port": "/dev/ttyUSB0"} # TODO test
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
])
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
from launch import LaunchDescription
|
||||||
|
from launch_ros.actions import Node
|
||||||
|
|
||||||
|
def generate_launch_description():
|
||||||
|
return LaunchDescription([
|
||||||
|
Node(
|
||||||
|
package="object_detection",
|
||||||
|
executable="multiflex_reader",
|
||||||
|
name="multiflex_reader",
|
||||||
|
parameters=[
|
||||||
|
{"multiflex_serial_port": "/dev/ttyACM0"}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
])
|
||||||
6
src/object_detection/msg/LidarReading.msg
Normal file
6
src/object_detection/msg/LidarReading.msg
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
float32 sensor_1
|
||||||
|
float32 sensor_2
|
||||||
|
float32 sensor_3
|
||||||
|
float32 sensor_4
|
||||||
|
float32[] imu_data
|
||||||
|
|
||||||
1
src/object_detection/msg/MultiflexReading.msg
Normal file
1
src/object_detection/msg/MultiflexReading.msg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
float32[6] distance_data
|
||||||
27
src/object_detection/package.xml
Normal file
27
src/object_detection/package.xml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||||
|
<package format="3">
|
||||||
|
<name>object_detection</name>
|
||||||
|
<version>0.0.0</version>
|
||||||
|
<description>Package to read the TeraBee lidar and multiflex sensors</description>
|
||||||
|
<maintainer email="semmer99@gmail.com">sem</maintainer>
|
||||||
|
<license>Apache License 2.0</license>
|
||||||
|
|
||||||
|
<buildtool_depend>ament_cmake</buildtool_depend>
|
||||||
|
<build_depend>rosidl_default_generators</build_depend>
|
||||||
|
<exec_depend>rosidl_default_runtime</exec_depend>
|
||||||
|
<member_of_group>rosidl_interface_packages</member_of_group>
|
||||||
|
|
||||||
|
<test_depend>ament_lint_auto</test_depend>
|
||||||
|
<test_depend>ament_lint_common</test_depend>
|
||||||
|
|
||||||
|
<build_depend>rclcpp</build_depend>
|
||||||
|
<build_depend>TerabeeApi</build_depend>
|
||||||
|
|
||||||
|
<exec_depend>TerabeeApi</exec_depend>
|
||||||
|
|
||||||
|
|
||||||
|
<export>
|
||||||
|
<build_type>ament_cmake</build_type>
|
||||||
|
</export>
|
||||||
|
</package>
|
||||||
121
src/object_detection/src/lidar_reader.cpp
Normal file
121
src/object_detection/src/lidar_reader.cpp
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
#include <chrono>
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "rclcpp/rclcpp.hpp"
|
||||||
|
#include "object_detection/msg/lidar_reading.hpp"
|
||||||
|
|
||||||
|
#include <terabee/ITerarangerFactory.hpp>
|
||||||
|
#include <terabee/ITerarangerTowerEvo.hpp>
|
||||||
|
#include <terabee/TowerDistanceData.hpp>
|
||||||
|
#include <terabee/ImuData.hpp>
|
||||||
|
|
||||||
|
using terabee::ImuData;
|
||||||
|
using terabee::ITerarangerTowerEvo;
|
||||||
|
using terabee::TowerDistanceData;
|
||||||
|
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
|
/* This example creates a subclass of Node and uses std::bind() to register a
|
||||||
|
* member function as a callback from the timer. */
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &os, const TowerDistanceData &d)
|
||||||
|
{
|
||||||
|
os << "[";
|
||||||
|
for (size_t i = 0; i < d.distance.size(); i++)
|
||||||
|
{
|
||||||
|
os << i << " " << d.distance[i] << (d.mask[i] ? " <new>, " : " <old>, ");
|
||||||
|
}
|
||||||
|
os << "\b\b"
|
||||||
|
<< " ]";
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &os, const ImuData &d)
|
||||||
|
{
|
||||||
|
os << "[";
|
||||||
|
for (size_t i = 0; i < d.data.size(); i++)
|
||||||
|
{
|
||||||
|
os << d.data[i] << ", ";
|
||||||
|
}
|
||||||
|
os << "\b\b"
|
||||||
|
<< " ]";
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
class LidarReader : public rclcpp::Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LidarReader()
|
||||||
|
: Node("lidar_reader")
|
||||||
|
{
|
||||||
|
|
||||||
|
rcl_interfaces::msg::ParameterDescriptor descriptor = rcl_interfaces::msg::ParameterDescriptor{};
|
||||||
|
descriptor.description = "serial port for the USB port of the LIDAR";
|
||||||
|
|
||||||
|
this->declare_parameter("lidar_serial_port", "/dev/ttyACM0", descriptor);
|
||||||
|
|
||||||
|
// publisher_ = this->create_publisher<object_detection::msg::LidarReading>("drone/object_detection", 10);
|
||||||
|
timer_ = this->create_wall_timer(500ms, std::bind(&LidarReader::read_lidar_data, this));
|
||||||
|
|
||||||
|
ITerarangerTowerEvo::ImuMode mode(ITerarangerTowerEvo::QuaternionLinearAcc);
|
||||||
|
|
||||||
|
factory = terabee::ITerarangerFactory::getFactory();
|
||||||
|
tower = factory->createTerarangerTowerEvo(this->get_parameter("lidar_serial_port").as_string());
|
||||||
|
|
||||||
|
if (!tower)
|
||||||
|
{
|
||||||
|
RCLCPP_ERROR(this->get_logger(), "Failed to create TerarangerTowerEvo");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tower->setImuMode(mode);
|
||||||
|
|
||||||
|
if (!tower->initialize())
|
||||||
|
{
|
||||||
|
RCLCPP_ERROR(this->get_logger(), "Failed to initialize TerarangerTowerEvo");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void read_lidar_data()
|
||||||
|
{
|
||||||
|
//TODO publish message with all data from lidar
|
||||||
|
// std::cout << "Distance = " << tower->getDistance() << std::endl;
|
||||||
|
// std::cout << "IMU = " << tower->getImuData() << std::endl;
|
||||||
|
|
||||||
|
// auto msg = object_detection::msg::LidarReading();
|
||||||
|
|
||||||
|
// msg.sensor_1 = tower->getDistance().distance.at(0);
|
||||||
|
// msg.sensor_2 = tower->getDistance().distance.at(2);
|
||||||
|
// msg.sensor_3 = tower->getDistance().distance.at(4);
|
||||||
|
// msg.sensor_4 = tower->getDistance().distance.at(6);
|
||||||
|
|
||||||
|
// ImuData imu_data = tower->getImuData();
|
||||||
|
|
||||||
|
// for (size_t i = 0; i < imu_data.data.size(); i++)
|
||||||
|
// {
|
||||||
|
// msg.imu_data.push_back(imu_data.data[i]);
|
||||||
|
// }
|
||||||
|
// // publisher_->publish(msg);
|
||||||
|
// RCLCPP_INFO(this->get_logger(), "Publishing message");
|
||||||
|
}
|
||||||
|
|
||||||
|
// rclcpp::Publisher<object_detection::msg::LidarReading>::SharedPtr publisher_;
|
||||||
|
rclcpp::TimerBase::SharedPtr timer_;
|
||||||
|
|
||||||
|
// terabee tower evo variables
|
||||||
|
std::unique_ptr<terabee::ITerarangerTowerEvo> tower;
|
||||||
|
std::unique_ptr<terabee::ITerarangerFactory> factory;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
rclcpp::init(argc, argv);
|
||||||
|
rclcpp::spin(std::make_shared<LidarReader>());
|
||||||
|
rclcpp::shutdown();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
81
src/object_detection/src/multiflex_reader.cpp
Normal file
81
src/object_detection/src/multiflex_reader.cpp
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
#include <chrono>
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "rclcpp/rclcpp.hpp"
|
||||||
|
#include "object_detection/msg/multiflex_reading.hpp"
|
||||||
|
|
||||||
|
#include <terabee/ITerarangerFactory.hpp>
|
||||||
|
#include <terabee/ITerarangerMultiflex.hpp>
|
||||||
|
#include <terabee/DistanceData.hpp>
|
||||||
|
|
||||||
|
using terabee::DistanceData;
|
||||||
|
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
|
class MultiflexReader : public rclcpp::Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MultiflexReader()
|
||||||
|
: Node("multiflex_reader")
|
||||||
|
{
|
||||||
|
rcl_interfaces::msg::ParameterDescriptor serial_port_descriptor = rcl_interfaces::msg::ParameterDescriptor{};
|
||||||
|
serial_port_descriptor.description = "Serial port of the USB port that the multiflex PCB is connected to.";
|
||||||
|
this->declare_parameter("multiflex_serial_port", "/dev/ttyACM0", serial_port_descriptor);
|
||||||
|
|
||||||
|
factory = terabee::ITerarangerFactory::getFactory();
|
||||||
|
multiflex = factory->createTerarangerMultiflex(this->get_parameter("multiflex_serial_port").as_string());
|
||||||
|
|
||||||
|
if (!multiflex)
|
||||||
|
{
|
||||||
|
RCLCPP_ERROR(this->get_logger(), "Failed to create multiflex");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!multiflex->initialize())
|
||||||
|
{
|
||||||
|
RCLCPP_ERROR(this->get_logger(), "Failed to initialize multiflex");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!multiflex->configureNumberOfSensors(0x3f))
|
||||||
|
{
|
||||||
|
RCLCPP_ERROR(this->get_logger(), "Failed to set the number of sensors to 6!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RCLCPP_INFO(this->get_logger(), "Multiflex initialized");
|
||||||
|
|
||||||
|
|
||||||
|
publisher_ = this->create_publisher<object_detection::msg::MultiflexReading>("drone/object_detection", 10);
|
||||||
|
timer_ = this->create_wall_timer(500ms, std::bind(&MultiflexReader::read_multiflex_data, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void read_multiflex_data()
|
||||||
|
{
|
||||||
|
terabee::DistanceData data = multiflex->getDistance();
|
||||||
|
auto msg = object_detection::msg::MultiflexReading();
|
||||||
|
for (size_t i = 0; i < data.size(); i++)
|
||||||
|
{
|
||||||
|
msg.distance_data[i] = data.distance[i];
|
||||||
|
}
|
||||||
|
publisher_->publish(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<terabee::ITerarangerFactory> factory;
|
||||||
|
std::unique_ptr<terabee::ITerarangerMultiflex> multiflex;
|
||||||
|
|
||||||
|
rclcpp::TimerBase::SharedPtr timer_;
|
||||||
|
rclcpp::Publisher<object_detection::msg::MultiflexReading>::SharedPtr publisher_;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
rclcpp::init(argc, argv);
|
||||||
|
rclcpp::spin(std::make_shared<MultiflexReader>());
|
||||||
|
rclcpp::shutdown();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
76
src/px4_connection/CMakeLists.txt
Normal file
76
src/px4_connection/CMakeLists.txt
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
project(px4_connection)
|
||||||
|
|
||||||
|
# Default to C99
|
||||||
|
if(NOT CMAKE_C_STANDARD)
|
||||||
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Default to C++14
|
||||||
|
if(NOT CMAKE_CXX_STANDARD)
|
||||||
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
|
add_compile_options(-Wall -Wextra -Wpedantic)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# find dependencies
|
||||||
|
find_package(ament_cmake REQUIRED)
|
||||||
|
find_package(rclcpp REQUIRED)
|
||||||
|
find_package(px4_ros_com REQUIRED)
|
||||||
|
find_package(px4_msgs REQUIRED)
|
||||||
|
find_package(px4_connection REQUIRED)
|
||||||
|
find_package(rosidl_default_generators REQUIRED)
|
||||||
|
|
||||||
|
rosidl_generate_interfaces(${PROJECT_NAME}
|
||||||
|
"srv/SetAttitude.srv"
|
||||||
|
)
|
||||||
|
|
||||||
|
include_directories(include)
|
||||||
|
add_executable(heartbeat src/heartbeat.cpp)
|
||||||
|
ament_target_dependencies(
|
||||||
|
heartbeat
|
||||||
|
rclcpp
|
||||||
|
px4_ros_com
|
||||||
|
px4_msgs
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(px4_controller src/px4_controller.cpp)
|
||||||
|
ament_target_dependencies(
|
||||||
|
px4_controller
|
||||||
|
rclcpp
|
||||||
|
px4_ros_com
|
||||||
|
px4_msgs
|
||||||
|
px4_connection
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(heartbeat PUBLIC
|
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||||
|
$<INSTALL_INTERFACE:include>)
|
||||||
|
|
||||||
|
target_include_directories(px4_controller PUBLIC
|
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||||
|
$<INSTALL_INTERFACE:include>)
|
||||||
|
|
||||||
|
install(TARGETS heartbeat px4_controller
|
||||||
|
DESTINATION lib/${PROJECT_NAME})
|
||||||
|
|
||||||
|
install(
|
||||||
|
DIRECTORY launch
|
||||||
|
DESTINATION share/${PROJECT_NAME}
|
||||||
|
)
|
||||||
|
|
||||||
|
if(BUILD_TESTING)
|
||||||
|
find_package(ament_lint_auto REQUIRED)
|
||||||
|
|
||||||
|
# the following line skips the linter which checks for copyrights
|
||||||
|
# uncomment the line when a copyright and license is not present in all source files
|
||||||
|
# set(ament_cmake_copyright_FOUND TRUE)
|
||||||
|
# the following line skips cpplint (only works in a git repo)
|
||||||
|
# uncomment the line when this package is not in a git repo
|
||||||
|
# set(ament_cmake_cpplint_FOUND TRUE)
|
||||||
|
ament_lint_auto_find_test_dependencies()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
ament_package()
|
||||||
8
src/px4_connection/include/attitude_msg_code.hpp
Normal file
8
src/px4_connection/include/attitude_msg_code.hpp
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef ATTITUDE_MSG_CODE_HPP
|
||||||
|
#define ATTITUDE_MSG_CODE_HPP
|
||||||
|
|
||||||
|
#define ATTITUDE_STATUS_OK 0
|
||||||
|
#define ATTITUDE_STATUS_ERROR 1
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
15
src/px4_connection/launch/px4_controller_heardbeat_launch.py
Normal file
15
src/px4_connection/launch/px4_controller_heardbeat_launch.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
from launch import LaunchDescription
|
||||||
|
from launch_ros.actions import Node
|
||||||
|
|
||||||
|
def generate_launch_description():
|
||||||
|
return LaunchDescription([
|
||||||
|
Node(
|
||||||
|
package="px4_connection",
|
||||||
|
executable="heartbeat"
|
||||||
|
),
|
||||||
|
Node(
|
||||||
|
package="px4_connection",
|
||||||
|
executable="px4_controller"
|
||||||
|
)
|
||||||
|
|
||||||
|
])
|
||||||
25
src/px4_connection/package.xml
Normal file
25
src/px4_connection/package.xml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||||
|
<package format="3">
|
||||||
|
<name>px4_connection</name>
|
||||||
|
<version>0.0.0</version>
|
||||||
|
<description>Package to communicate with PX4 through the XRCE-DDS bridge</description>
|
||||||
|
<maintainer email="semmer99@gmail.com">ubuntu</maintainer>
|
||||||
|
<license>Apache License 2.0</license>
|
||||||
|
|
||||||
|
<buildtool_depend>ament_cmake</buildtool_depend>
|
||||||
|
<buildtool_depend>rosidl_default_generators</buildtool_depend>
|
||||||
|
|
||||||
|
<exec_depend>rosidl_default_runtime</exec_depend>
|
||||||
|
<member_of_group>rosidl_interface_packages</member_of_group>
|
||||||
|
|
||||||
|
|
||||||
|
<depend>rclcpp</depend>
|
||||||
|
|
||||||
|
<test_depend>ament_lint_auto</test_depend>
|
||||||
|
<test_depend>ament_lint_common</test_depend>
|
||||||
|
|
||||||
|
<export>
|
||||||
|
<build_type>ament_cmake</build_type>
|
||||||
|
</export>
|
||||||
|
</package>
|
||||||
75
src/px4_connection/src/heartbeat.cpp
Normal file
75
src/px4_connection/src/heartbeat.cpp
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
We need to send attitude setpoints to be able to arm the drone:
|
||||||
|
https://mavlink.io/en/messages/common.html#SET_ATTITUDE_TARGET
|
||||||
|
We need attitude setpoints because we don't have a GPS:
|
||||||
|
https://discuss.px4.io/t/cannot-arm-drone-with-companion-computer-arming-denied-manual-control-lost/31565/9
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
#include "rclcpp/rclcpp.hpp"
|
||||||
|
|
||||||
|
#include <px4_msgs/msg/offboard_control_mode.hpp>
|
||||||
|
// #include <px4_msgs/msg/timesync.hpp>
|
||||||
|
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
|
class HeartBeat : public rclcpp::Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HeartBeat() : Node("setpoint_sender")
|
||||||
|
{
|
||||||
|
// create a publisher on the offboard control mode topic
|
||||||
|
offboard_control_mode_publisher_ = this->create_publisher<px4_msgs::msg::OffboardControlMode>("/fmu/in/offboard_control_mode", 10);
|
||||||
|
// create timer to send heartbeat messages (offboard control) every 100ms
|
||||||
|
timer_ = this->create_wall_timer(100ms, std::bind(&HeartBeat::send_heartbeat, this));
|
||||||
|
start_time = this->get_clock()->now().seconds();
|
||||||
|
RCLCPP_INFO(this->get_logger(), "done initializing at %d seconds. Sending heartbeat...", start_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Publish offboard control mode messages as a heartbeat.
|
||||||
|
* Only the attitude is enabled, because that is how the drone will be controlled.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void send_heartbeat()
|
||||||
|
{
|
||||||
|
// set message to enable attitude
|
||||||
|
auto msg = px4_msgs::msg::OffboardControlMode();
|
||||||
|
msg.position = false;
|
||||||
|
msg.velocity = true;
|
||||||
|
msg.acceleration = false;
|
||||||
|
msg.attitude = false;
|
||||||
|
msg.body_rate = false;
|
||||||
|
msg.actuator = false;
|
||||||
|
|
||||||
|
// get timestamp and publish message
|
||||||
|
msg.timestamp = this->get_clock()->now().nanoseconds() / 1000;
|
||||||
|
offboard_control_mode_publisher_->publish(msg);
|
||||||
|
// RCLCPP_INFO(this->get_logger(), "sent offboard control mode message!");
|
||||||
|
|
||||||
|
// check if 5 seconds have elapsed
|
||||||
|
// if (this->get_clock()->now().seconds() - start_time > 5)
|
||||||
|
// {
|
||||||
|
// RCLCPP_INFO(this->get_logger(), "5 seconds elapsed!");
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
rclcpp::Publisher<px4_msgs::msg::OffboardControlMode>::SharedPtr offboard_control_mode_publisher_;
|
||||||
|
rclcpp::TimerBase::SharedPtr timer_;
|
||||||
|
double start_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
rclcpp::init(argc, argv);
|
||||||
|
rclcpp::spin(std::make_shared<HeartBeat>());
|
||||||
|
rclcpp::shutdown();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
277
src/px4_connection/src/px4_controller.cpp
Normal file
277
src/px4_connection/src/px4_controller.cpp
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
We need to send attitude setpoints to be able to arm the drone:
|
||||||
|
https://mavlink.io/en/messages/common.html#SET_ATTITUDE_TARGET
|
||||||
|
We need attitude setpoints because we don't have a GPS:
|
||||||
|
https://discuss.px4.io/t/cannot-arm-drone-with-companion-computer-arming-denied-manual-control-lost/31565/9
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "rclcpp/rclcpp.hpp"
|
||||||
|
// #include "attitude_msg_code.hpp"
|
||||||
|
|
||||||
|
#include <px4_msgs/msg/vehicle_attitude_setpoint.hpp>
|
||||||
|
#include <px4_msgs/msg/trajectory_setpoint.hpp>
|
||||||
|
// #include <px4_msgs/msg/timesync.hpp>
|
||||||
|
#include <px4_msgs/msg/vehicle_command.hpp>
|
||||||
|
#include <px4_msgs/msg/vehicle_control_mode.hpp>
|
||||||
|
|
||||||
|
#include <px4_connection/srv/set_attitude.hpp>
|
||||||
|
// #include <px4_msgs/msg/offboard_control_mode.hpp>
|
||||||
|
|
||||||
|
#define D_SPEED(x) -x - 9.81
|
||||||
|
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
|
class PX4Controller : public rclcpp::Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PX4Controller() : Node("px4_controller")
|
||||||
|
{
|
||||||
|
// create a publisher on the vehicle attitude setpoint topic
|
||||||
|
vehicle_setpoint_publisher_ = this->create_publisher<px4_msgs::msg::VehicleAttitudeSetpoint>("/fmu/in/vehicle_attitude_setpoint", 10);
|
||||||
|
vehicle_command_publisher_ = this->create_publisher<px4_msgs::msg::VehicleCommand>("/fmu/in/vehicle_command", 10);
|
||||||
|
trajectory_setpoint_publisher = this->create_publisher<px4_msgs::msg::TrajectorySetpoint>("/fmu/in/trajectory_setpoint", 10);
|
||||||
|
// offboard_control_mode_publisher_ = this->create_publisher<px4_msgs::msg::OffboardControlMode>("/fmu/in/offboard_control_mode", 10);
|
||||||
|
|
||||||
|
set_attitude_service_ = this->create_service<px4_connection::srv::SetAttitude>("set_attitude", std::bind(&PX4Controller::set_setpoint, this, std::placeholders::_1,std::placeholders::_2,std::placeholders::_3));
|
||||||
|
|
||||||
|
// service_ptr_ = this->create_service<std_srvs::srv::Empty>(
|
||||||
|
// "test_service",
|
||||||
|
// std::bind(&ServiceNode::service_callback, this, _1, _2, _3)
|
||||||
|
// );
|
||||||
|
|
||||||
|
// create timer to send vehicle attitude setpoints every second
|
||||||
|
timer_ = this->create_wall_timer(100ms, std::bind(&PX4Controller::send_setpoint, this));
|
||||||
|
|
||||||
|
start_time_ = this->get_clock()->now().seconds();
|
||||||
|
RCLCPP_INFO(this->get_logger(), "finished initializing at %f seconds.", start_time_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
rclcpp::Publisher<px4_msgs::msg::VehicleAttitudeSetpoint>::SharedPtr vehicle_setpoint_publisher_;
|
||||||
|
rclcpp::Publisher<px4_msgs::msg::TrajectorySetpoint>::SharedPtr trajectory_setpoint_publisher;
|
||||||
|
rclcpp::Publisher<px4_msgs::msg::VehicleCommand>::SharedPtr vehicle_command_publisher_;
|
||||||
|
rclcpp::Service<px4_connection::srv::SetAttitude>::SharedPtr set_attitude_service_;
|
||||||
|
|
||||||
|
// rclcpp::Publisher<px4_msgs::msg::OffboardControlMode>::SharedPtr offboard_control_mode_publisher_;
|
||||||
|
|
||||||
|
rclcpp::TimerBase::SharedPtr timer_;
|
||||||
|
double start_time_;
|
||||||
|
bool has_sent_status = false;
|
||||||
|
bool flying = false;
|
||||||
|
bool has_swithed = false;
|
||||||
|
int setpoint_count = 0;
|
||||||
|
float thrust = 0.5;
|
||||||
|
bool ready_to_fly = false;
|
||||||
|
float cur_yaw = 0;
|
||||||
|
|
||||||
|
float last_setpoint[3] = {0,0,0};
|
||||||
|
float last_angle = 0;
|
||||||
|
|
||||||
|
void set_setpoint(
|
||||||
|
const std::shared_ptr<rmw_request_id_t> request_header,
|
||||||
|
const std::shared_ptr<px4_connection::srv::SetAttitude::Request> request,
|
||||||
|
const std::shared_ptr<px4_connection::srv::SetAttitude::Response> response)
|
||||||
|
{
|
||||||
|
last_setpoint[0] = request->x_speed;
|
||||||
|
last_setpoint[1] = request->y_speed;
|
||||||
|
last_setpoint[2] = request->x_speed;
|
||||||
|
|
||||||
|
last_angle = degrees_to_radians(request->angle);
|
||||||
|
|
||||||
|
response->status = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_trajectory_setpoint()
|
||||||
|
{
|
||||||
|
|
||||||
|
auto msg = px4_msgs::msg::TrajectorySetpoint();
|
||||||
|
if (this->get_clock()->now().seconds() - start_time_ < 10)
|
||||||
|
{
|
||||||
|
msg.velocity[0] = 0;
|
||||||
|
msg.velocity[1] = 0;
|
||||||
|
msg.velocity[2] = D_SPEED(10);
|
||||||
|
msg.yawspeed = 0;
|
||||||
|
msg.yaw = -3.14;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!has_swithed)
|
||||||
|
{
|
||||||
|
RCLCPP_INFO(this->get_logger(), "switching to 0 vel");
|
||||||
|
has_swithed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.velocity[0] = last_setpoint[0];
|
||||||
|
msg.velocity[1] = last_setpoint[1];
|
||||||
|
msg.velocity[2] = D_SPEED(last_setpoint[2]);
|
||||||
|
msg.yawspeed = 0.5;
|
||||||
|
msg.yaw = last_angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.timestamp = this->get_clock()->now().nanoseconds() / 1000;
|
||||||
|
|
||||||
|
trajectory_setpoint_publisher->publish(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_attitude_setpoint()
|
||||||
|
{
|
||||||
|
if (setpoint_count % 20 == 0 && thrust <= 1)
|
||||||
|
{
|
||||||
|
thrust += 0.1;
|
||||||
|
RCLCPP_INFO(this->get_logger(), "increasing thrust to %f", thrust);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set message to enable attitude
|
||||||
|
auto msg = px4_msgs::msg::VehicleAttitudeSetpoint();
|
||||||
|
// result quaternion
|
||||||
|
std::array<float, 4> q = {0, 0, 0, 0};
|
||||||
|
|
||||||
|
if (this->get_clock()->now().seconds() - start_time_ < 10)
|
||||||
|
{
|
||||||
|
// move up?
|
||||||
|
msg.thrust_body[0] = 0; // north
|
||||||
|
msg.thrust_body[1] = 0; // east
|
||||||
|
msg.thrust_body[2] = -0.8; // down, 100% thrust up
|
||||||
|
|
||||||
|
calculate_quaternion(q, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (this->get_clock()->now().seconds() - start_time_ < 30)
|
||||||
|
{
|
||||||
|
if (!has_swithed)
|
||||||
|
{
|
||||||
|
RCLCPP_INFO(this->get_logger(), "changing to 0.5 thrust");
|
||||||
|
has_swithed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.thrust_body[0] = 0; // north
|
||||||
|
msg.thrust_body[1] = 0; // east
|
||||||
|
msg.thrust_body[2] = -0.5; // down, 100% thrust up
|
||||||
|
|
||||||
|
calculate_quaternion(q, 0, 0, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (flying)
|
||||||
|
{
|
||||||
|
publish_vehicle_command(px4_msgs::msg::VehicleCommand::VEHICLE_CMD_COMPONENT_ARM_DISARM, 0.0, 0);
|
||||||
|
flying = false;
|
||||||
|
RCLCPP_INFO(this->get_logger(), "Disarm command sent after 30 seconds");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.q_d[0] = q.at(0);
|
||||||
|
msg.q_d[1] = q.at(1);
|
||||||
|
msg.q_d[2] = q.at(2);
|
||||||
|
msg.q_d[3] = q.at(3);
|
||||||
|
|
||||||
|
msg.yaw_sp_move_rate = 0;
|
||||||
|
msg.reset_integral = false;
|
||||||
|
msg.fw_control_yaw_wheel = false;
|
||||||
|
|
||||||
|
msg.timestamp = this->get_clock()->now().nanoseconds() / 1000;
|
||||||
|
vehicle_setpoint_publisher_->publish(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send setpoints to PX4. First, 20 setpoints will be sent before offboard mode will be engaged and the drone will be armed.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void send_setpoint()
|
||||||
|
{
|
||||||
|
// increase amount of setpoints sent
|
||||||
|
setpoint_count++;
|
||||||
|
|
||||||
|
ready_to_fly = setpoint_count == 20;
|
||||||
|
// after 20 setpoints, send arm command to make drone actually fly
|
||||||
|
if (ready_to_fly)
|
||||||
|
{
|
||||||
|
// switch to offboard mode and arm
|
||||||
|
|
||||||
|
// set to offboard mode
|
||||||
|
this->publish_vehicle_command(px4_msgs::msg::VehicleCommand::VEHICLE_CMD_DO_SET_MODE, 1, 6);
|
||||||
|
RCLCPP_INFO(this->get_logger(), "Set to offboard mode");
|
||||||
|
// arm the drone
|
||||||
|
this->publish_vehicle_command(px4_msgs::msg::VehicleCommand::VEHICLE_CMD_COMPONENT_ARM_DISARM, 1.0, 0);
|
||||||
|
|
||||||
|
RCLCPP_INFO(this->get_logger(), "Arm command sent");
|
||||||
|
flying = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
send_trajectory_setpoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Publish vehicle commands
|
||||||
|
* @param command Command code (matches VehicleCommand and MAVLink MAV_CMD codes)
|
||||||
|
* @param param1 Command parameter 1
|
||||||
|
* @param param2 Command parameter 2
|
||||||
|
*/
|
||||||
|
void publish_vehicle_command(uint16_t command, float param1, float param2)
|
||||||
|
{
|
||||||
|
px4_msgs::msg::VehicleCommand msg{};
|
||||||
|
msg.param1 = param1;
|
||||||
|
msg.param2 = param2;
|
||||||
|
msg.command = command;
|
||||||
|
msg.target_system = 1;
|
||||||
|
msg.target_component = 1;
|
||||||
|
msg.source_system = 1;
|
||||||
|
msg.source_component = 1;
|
||||||
|
msg.from_external = true;
|
||||||
|
msg.timestamp = this->get_clock()->now().nanoseconds() / 1000;
|
||||||
|
vehicle_command_publisher_->publish(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief calculates a quaternion based on the given input values
|
||||||
|
*
|
||||||
|
* @param ptr array of result quaternion. Must be of size 4.
|
||||||
|
* @param heading desired heading (yaw) in radians.
|
||||||
|
* @param attitude desired attitude (pitch) in radians.
|
||||||
|
* @param bank desired bank (roll) in radians.
|
||||||
|
*/
|
||||||
|
static void calculate_quaternion(std::array<float, 4> ptr, float heading, float attitude, float bank)
|
||||||
|
{
|
||||||
|
|
||||||
|
float c1 = cos(heading / 2);
|
||||||
|
float c2 = cos(attitude / 2);
|
||||||
|
float c3 = cos(bank / 2);
|
||||||
|
float s1 = sin(heading / 2);
|
||||||
|
float s2 = sin(attitude / 2);
|
||||||
|
float s3 = sin(bank / 2);
|
||||||
|
|
||||||
|
float c1c2 = c1 * c2;
|
||||||
|
float s1s2 = s1 * s2;
|
||||||
|
|
||||||
|
ptr.at(0) = c1c2 * c3 - s1s2 * s3; // w
|
||||||
|
ptr.at(1) = c1c2 * s3 + s1s2 * c3; // x
|
||||||
|
ptr.at(2) = s1 * c2 * c3 + c1 * s2 * s3; // y
|
||||||
|
ptr.at(3) = c1 * s2 * c3 - s1 * c2 * s3; // z
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief converts degrees to radians
|
||||||
|
*
|
||||||
|
* @param deg angle in degrees
|
||||||
|
* @return float new angle in radians
|
||||||
|
*/
|
||||||
|
static float degrees_to_radians(float deg)
|
||||||
|
{
|
||||||
|
return deg * (M_PI / 180.0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
rclcpp::init(argc, argv);
|
||||||
|
|
||||||
|
rclcpp::Node::SharedPtr node = std::make_shared<PX4Controller>();
|
||||||
|
rclcpp::spin(node);
|
||||||
|
rclcpp::shutdown();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
9
src/px4_connection/srv/SetAttitude.srv
Normal file
9
src/px4_connection/srv/SetAttitude.srv
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#all speeds are in meters/second
|
||||||
|
float32 x_speed
|
||||||
|
float32 y_speed
|
||||||
|
float32 z_speed
|
||||||
|
|
||||||
|
#angle is in degrees
|
||||||
|
float32 angle
|
||||||
|
---
|
||||||
|
int8 status
|
||||||
Submodule src/px4_msgs updated: 4db0a3f14e...b64ef0475c
Reference in New Issue
Block a user