Skip to content

Commit

Permalink
feat(nebula_hw_interfaces): better UDP socket (#231)
Browse files Browse the repository at this point in the history
* feat(udp): a new UDP socket implementation

Signed-off-by: Max SCHMELLER <[email protected]>

* chore(udp): more error handling and doc comments

Signed-off-by: Max SCHMELLER <[email protected]>

* chore(udp): always enable socket reuse

Signed-off-by: Max SCHMELLER <[email protected]>

* chore(udp): clean up C-style code

Signed-off-by: Max SCHMELLER <[email protected]>

* chore(udp): remove unnecessary double parens

Signed-off-by: Max SCHMELLER <[email protected]>

* feat(udp): use poll to prevent blocking when there is no received data

Signed-off-by: Max SCHMELLER <[email protected]>

* chore(udp): differentiate between socket and usage-related errors

Signed-off-by: Max SCHMELLER <[email protected]>

* feat(udp): allow setting receive buffer size

Signed-off-by: Max SCHMELLER <[email protected]>

* chore(udp): use uint8_t because std::byte is annoying to refactor into everywhere

Signed-off-by: Max SCHMELLER <[email protected]>

* fix(udp): update state correctly when `bind()` is called

Signed-off-by: Max SCHMELLER <[email protected]>

* feat(udp): monitor socket packet drops

Signed-off-by: Max SCHMELLER <[email protected]>

* feat(udp): add explicit unsubscribe function to facilitate clean shutdown

Signed-off-by: Max SCHMELLER <[email protected]>

* chore(expected): add stdexcept include

Signed-off-by: Max SCHMELLER <[email protected]>

* feat(udp): report when messages have been truncated

Signed-off-by: Max SCHMELLER <[email protected]>

* chore(udp): relax some usage requirements

Signed-off-by: Max SCHMELLER <[email protected]>

* test(udp): add most of the unit tests for udp socket

Signed-off-by: Max SCHMELLER <[email protected]>

* ci(pre-commit): autofix

* chore(cspell): add OVFL to dictionary

Signed-off-by: Max SCHMELLER <[email protected]>

* fix(udp): return correctly truncated buffer when oversized packet is received

Signed-off-by: Max SCHMELLER <[email protected]>

* chore(udp): uniform initialization for buffer_size_

Signed-off-by: Max SCHMELLER <[email protected]>

* chore(udp): disallow re-initializing socket

Signed-off-by: Max SCHMELLER <[email protected]>

* chore(udp): make error value checking consistent (== -1)

Signed-off-by: Max SCHMELLER <[email protected]>

* chore(udp): add explanatory comment on handling of 0-length datagrams

Signed-off-by: Max SCHMELLER <[email protected]>

* chore(udp): disallow binding to broadcast IP

Signed-off-by: Max SCHMELLER <[email protected]>

* chore(udp): bind to host IP instead of INADDR_ANY in non-multicast case

Signed-off-by: Max SCHMELLER <[email protected]>

* feat(udp): make polling interval configurable

Signed-off-by: Max SCHMELLER <[email protected]>

* chore(udp): rename ReceiveMetadata to RxMetadata

Signed-off-by: Max SCHMELLER <[email protected]>

* chore(udp): parse IP addresses with error checking

Signed-off-by: Max SCHMELLER <[email protected]>

* test(udp): update and fix tests after changes of recent commits

Signed-off-by: Max SCHMELLER <[email protected]>

* feat(expected): add shorthand `value_or_throw()` function

Signed-off-by: Max SCHMELLER <[email protected]>

* feat(udp): refactor to typestate-based builder pattern to make misuse a compiler error

Signed-off-by: Max SCHMELLER <[email protected]>

* ci(pre-commit): autofix

* chore(udp): replace `-1` with `uninitialized` in `SockFd` for clarity

Signed-off-by: Max SCHMELLER <[email protected]>

* chore(udp): mark SockFd constructor explicit

Signed-off-by: Max SCHMELLER <[email protected]>

* fix(udp): enforce that at most one multicast group is joined

Signed-off-by: Max SCHMELLER <[email protected]>

* chore(udp): reorder UdpSocket class to reduce number of needed visibility modifiers

Signed-off-by: Max SCHMELLER <[email protected]>

* fix(udp): make UDP socket object move-constructible to enable things like optional.emplace() etc.

Signed-off-by: Max SCHMELLER <[email protected]>

---------

Signed-off-by: Max SCHMELLER <[email protected]>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
mojomex and pre-commit-ci[bot] authored Dec 23, 2024
1 parent 97959dd commit dc69e52
Show file tree
Hide file tree
Showing 6 changed files with 769 additions and 6 deletions.
1 change: 1 addition & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"nproc",
"nsec",
"ntoa",
"OVFL",
"pandar",
"PANDAR",
"PANDARAT",
Expand Down
8 changes: 8 additions & 0 deletions nebula_common/include/nebula_common/util/expected.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#pragma once

#include <exception>
#include <stdexcept>
#include <string>
#include <variant>

Expand Down Expand Up @@ -78,6 +79,13 @@ struct expected
throw std::runtime_error(error_msg);
}

/// @brief If the instance has a value, return the value, else throw the stored error instance.
T value_or_throw()
{
if (has_value()) return value();
throw error();
}

/// @brief Retrieve the error, or throw `bad_expected_access` if a value is contained.
/// @return The error of type `E`
E error()
Expand Down
21 changes: 15 additions & 6 deletions nebula_hw_interfaces/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ cmake_minimum_required(VERSION 3.14)
project(nebula_hw_interfaces)

# Default to C++17
if (NOT CMAKE_CXX_STANDARD)
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 17)
endif ()
endif()

if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic -Wunused-function)
endif ()
endif()

find_package(ament_cmake_auto REQUIRED)
find_package(boost_tcp_driver)
Expand Down Expand Up @@ -53,7 +53,6 @@ target_link_libraries(nebula_hw_interfaces_velodyne PUBLIC
${boost_tcp_driver_LIBRARIES}
${boost_udp_driver_LIBRARIES}
${velodyne_msgs_TARGETS}

)
target_include_directories(nebula_hw_interfaces_velodyne PUBLIC
${boost_udp_driver_INCLUDE_DIRS}
Expand All @@ -68,7 +67,6 @@ target_link_libraries(nebula_hw_interfaces_robosense PUBLIC
${boost_tcp_driver_LIBRARIES}
${boost_udp_driver_LIBRARIES}
${robosense_msgs_TARGETS}

)
target_include_directories(nebula_hw_interfaces_robosense PUBLIC
${boost_udp_driver_INCLUDE_DIRS}
Expand Down Expand Up @@ -100,6 +98,17 @@ install(DIRECTORY include/ DESTINATION include/${PROJECT_NAME})
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
ament_lint_auto_find_test_dependencies()

find_package(ament_cmake_gtest REQUIRED)

ament_add_gtest(test_udp
test/common/test_udp.cpp
)

target_include_directories(test_udp PUBLIC
${nebula_common_INCLUDE_DIRS}
include
test)
endif()

ament_export_include_directories("include/${PROJECT_NAME}")
Expand Down
Loading

0 comments on commit dc69e52

Please sign in to comment.