From 43a7900e897ea4ba73a1297ebd88c4fa0ffaa19c Mon Sep 17 00:00:00 2001 From: Caian Benedicto Date: Wed, 13 Dec 2023 18:45:44 -0300 Subject: [PATCH 1/4] Add support for wiringpi and linux_arm --- extra_script.py | 8 ++++++-- library.json | 6 +++--- metas/linux.meta | 20 ++++++++++++++++++++ 3 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 metas/linux.meta diff --git a/extra_script.py b/extra_script.py index 5fb4421c..2d40072a 100644 --- a/extra_script.py +++ b/extra_script.py @@ -30,9 +30,13 @@ global_env = DefaultEnvironment() board = env['BOARD'] framework = env['PIOFRAMEWORK'][0] +platform = env.get('PIOPLATFORM', None) extra_packages_path = "{}/extra_packages".format(env['PROJECT_DIR']) -selected_board_meta = boards_metas[board] if board in boards_metas else "colcon.meta" +if platform == 'linux_arm': + selected_board_meta = 'linux.meta' +else: + selected_board_meta = boards_metas[board] if board in boards_metas else "colcon.meta" # Retrieve the required transport. Default iron microros_distro = global_env.BoardConfig().get("microros_distro", "iron") @@ -156,4 +160,4 @@ def update_env(): if set(["clean_microros", "_idedata", "idedata"]).isdisjoint(set(COMMAND_LINE_TARGETS)): build_microros() -update_env() \ No newline at end of file +update_env() diff --git a/library.json b/library.json index 2ca60302..d0a866db 100755 --- a/library.json +++ b/library.json @@ -25,6 +25,6 @@ "extraScript": "./extra_script.py" }, - "frameworks": "arduino", - "platforms": "teensy, https://github.com/platformio/platform-espressif32.git#feature/arduino-upstream, atmelsam, raspberrypi, ststm32" -} \ No newline at end of file + "frameworks": "arduino, wiringpi", + "platforms": "teensy, https://github.com/platformio/platform-espressif32.git#feature/arduino-upstream, atmelsam, raspberrypi, ststm32, linux_arm" +} diff --git a/metas/linux.meta b/metas/linux.meta new file mode 100644 index 00000000..109b4f0a --- /dev/null +++ b/metas/linux.meta @@ -0,0 +1,20 @@ +{ + "names": { + "rcutils": { + "cmake-args": [ + "-DCMAKE_C_FLAGS=-D_GNU_SOURCE" + ] + }, + "rmw_microxrcedds": { + "cmake-args": [ + "-DRMW_UXRCE_MAX_NODES=1", + "-DRMW_UXRCE_MAX_PUBLISHERS=10", + "-DRMW_UXRCE_MAX_SUBSCRIPTIONS=5", + "-DRMW_UXRCE_MAX_SERVICES=1", + "-DRMW_UXRCE_MAX_CLIENTS=1", + "-DRMW_UXRCE_MAX_HISTORY=4", + "-DRMW_UXRCE_TRANSPORT=custom" + ] + } + } +} From 571a663d3e93faf4ab01d2bceb4344c8d550ade0 Mon Sep 17 00:00:00 2001 From: Caian Benedicto Date: Wed, 13 Dec 2023 18:47:20 -0300 Subject: [PATCH 2/4] Add posix socket implementation --- .../wiringpi/socket/micro_ros_transport.cpp | 84 +++++++++++++++++++ .../wiringpi/socket/micro_ros_transport.h | 21 +++++ 2 files changed, 105 insertions(+) create mode 100644 platform_code/wiringpi/socket/micro_ros_transport.cpp create mode 100644 platform_code/wiringpi/socket/micro_ros_transport.h diff --git a/platform_code/wiringpi/socket/micro_ros_transport.cpp b/platform_code/wiringpi/socket/micro_ros_transport.cpp new file mode 100644 index 00000000..cf10344d --- /dev/null +++ b/platform_code/wiringpi/socket/micro_ros_transport.cpp @@ -0,0 +1,84 @@ +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +extern "C" { + +static int fd; + +bool platformio_transport_open(struct uxrCustomTransport * transport) +{ + const auto * locator = (const struct micro_ros_agent_locator *) transport->args; + + struct addrinfo hints; + + memset(&hints, 0, sizeof(hints)); + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_NUMERICSERV; + hints.ai_protocol = 0; + + const auto port_s = std::to_string(locator->port); + struct addrinfo * p_addrs = nullptr; + + if(getaddrinfo(locator->address, port_s.c_str(), &hints, &p_addrs) != 0) + return false; + + struct addrinfo * p_addr; + + for(p_addr = p_addrs; p_addr != nullptr; p_addr = p_addr->ai_next){ + if(0 > (fd = socket(p_addr->ai_family, p_addr->ai_socktype, p_addr->ai_protocol))) + continue; + + if(0 == connect(fd, p_addr->ai_addr, p_addr->ai_addrlen)) + break; + + close(fd); + } + + freeaddrinfo(p_addrs); + + return p_addr != nullptr; +} + +bool platformio_transport_close(struct uxrCustomTransport * transport) +{ + close(fd); + return true; +} + +size_t platformio_transport_write(struct uxrCustomTransport * transport, const uint8_t *buf, size_t len, uint8_t *) +{ + auto ret = send(fd, buf, len, 0); + return ret < 0 ? 0 : (size_t)ret; +} + +size_t platformio_transport_read(struct uxrCustomTransport * transport, uint8_t *buf, size_t len, int timeout, uint8_t *) +{ + struct pollfd pfd; + int ret; + + pfd.fd = fd; + pfd.events = POLLIN; + ret = poll(&pfd, 1, timeout); + switch(ret){ + case -1: + case 0: + return 0; + default: + ret = recv(fd, buf, len, 0); + return ret < 0 ? 0 : (size_t)ret; + } +} + +} diff --git a/platform_code/wiringpi/socket/micro_ros_transport.h b/platform_code/wiringpi/socket/micro_ros_transport.h new file mode 100644 index 00000000..ab3138f6 --- /dev/null +++ b/platform_code/wiringpi/socket/micro_ros_transport.h @@ -0,0 +1,21 @@ +#include + +struct micro_ros_agent_locator { + char * address; + int port; +}; + +static inline void set_microros_socket_transports(const char * agent_address, uint16_t agent_port){ + static struct micro_ros_agent_locator locator; + locator.address = strdup(agent_address); + locator.port = agent_port; + + rmw_uros_set_custom_transport( + false, + (void *) &locator, + platformio_transport_open, + platformio_transport_close, + platformio_transport_write, + platformio_transport_read + ); +} From 5059ebc7b8f68b4676c375ef92cf5ee3e4091623 Mon Sep 17 00:00:00 2001 From: Caian Benedicto Date: Sat, 16 Dec 2023 07:26:53 -0300 Subject: [PATCH 3/4] Update README --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fd2842e8..ed287873 100755 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ Supported boards are: | `esp32dev` | `espressif32` | `arduino` | `serial`
`wifi` | `colcon.meta` | | `nanorp2040connect` | `raspberrypi` | `arduino` | `serial`
`wifi_nina` | `colcon_verylowmem.meta` | | `pico` | `raspberrypi` | `arduino` | `serial` | `colcon.meta`| +| `raspberrypi_1b`
`raspberrypi_2b`
`raspberrypi_3b`
`raspberrypi_zero` | `linux_arm` | `wiringpi` | `socket` | `linux.meta`| The community is encouraged to open pull request with custom use cases. @@ -52,7 +53,7 @@ The community is encouraged to open pull request with custom use cases. ```bash apt install -y git cmake python3-pip ``` - + ### Platform specific requirements #### MacOS @@ -132,6 +133,15 @@ The transport can be configured with the `board_microros_transport = set_microros_native_ethernet_transports(local_mac, local_ip, agent_ip, agent_port); ``` + - `socket` + + ```c + const char* agent_ip = "192.168.1.113"; + uint16_t agent_port = 8888; + + set_microros_socket_transports(agent_ip, agent_port); + ``` + - `custom` The user will need to write transport functions in app code and provide it to the micro-ROS library using [`rmw_uros_set_custom_transport()` API](https://micro.ros.org/docs/tutorials/advanced/create_custom_transports/) From 7cbd961682388a884819dc0e9158354edc2aca49 Mon Sep 17 00:00:00 2001 From: Caian Benedicto Date: Sat, 16 Dec 2023 07:35:16 -0300 Subject: [PATCH 4/4] Make socket transport independent on the framework --- extra_script.py | 4 +++- .../{wiringpi => linux}/socket/micro_ros_transport.cpp | 0 .../{wiringpi => linux}/socket/micro_ros_transport.h | 0 3 files changed, 3 insertions(+), 1 deletion(-) rename platform_code/{wiringpi => linux}/socket/micro_ros_transport.cpp (100%) rename platform_code/{wiringpi => linux}/socket/micro_ros_transport.h (100%) diff --git a/extra_script.py b/extra_script.py index 2d40072a..b0fbc46c 100644 --- a/extra_script.py +++ b/extra_script.py @@ -29,13 +29,15 @@ main_path = os.path.realpath(".") global_env = DefaultEnvironment() board = env['BOARD'] -framework = env['PIOFRAMEWORK'][0] platform = env.get('PIOPLATFORM', None) extra_packages_path = "{}/extra_packages".format(env['PROJECT_DIR']) if platform == 'linux_arm': + # Transports built for linux do not depend on the framework + framework = 'linux' selected_board_meta = 'linux.meta' else: + framework = env['PIOFRAMEWORK'][0] selected_board_meta = boards_metas[board] if board in boards_metas else "colcon.meta" # Retrieve the required transport. Default iron diff --git a/platform_code/wiringpi/socket/micro_ros_transport.cpp b/platform_code/linux/socket/micro_ros_transport.cpp similarity index 100% rename from platform_code/wiringpi/socket/micro_ros_transport.cpp rename to platform_code/linux/socket/micro_ros_transport.cpp diff --git a/platform_code/wiringpi/socket/micro_ros_transport.h b/platform_code/linux/socket/micro_ros_transport.h similarity index 100% rename from platform_code/wiringpi/socket/micro_ros_transport.h rename to platform_code/linux/socket/micro_ros_transport.h