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/) diff --git a/extra_script.py b/extra_script.py index 5fb4421c..b0fbc46c 100644 --- a/extra_script.py +++ b/extra_script.py @@ -29,10 +29,16 @@ 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']) -selected_board_meta = boards_metas[board] if board in boards_metas else "colcon.meta" +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 microros_distro = global_env.BoardConfig().get("microros_distro", "iron") @@ -156,4 +162,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" + ] + } + } +} diff --git a/platform_code/linux/socket/micro_ros_transport.cpp b/platform_code/linux/socket/micro_ros_transport.cpp new file mode 100644 index 00000000..cf10344d --- /dev/null +++ b/platform_code/linux/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/linux/socket/micro_ros_transport.h b/platform_code/linux/socket/micro_ros_transport.h new file mode 100644 index 00000000..ab3138f6 --- /dev/null +++ b/platform_code/linux/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 + ); +}