Skip to content

Commit

Permalink
Update external transports API (micro-ROS#38)
Browse files Browse the repository at this point in the history
* Update external transports API

* Revert branches

* Fix

* Update

* Update

* Update CI
  • Loading branch information
pablogs9 authored Feb 9, 2021
1 parent c0b5926 commit 8bb5c13
Show file tree
Hide file tree
Showing 14 changed files with 261 additions and 7 deletions.
11 changes: 11 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,15 @@ jobs:
. $IDF_PATH/export.sh
cd micro_ros_espidf_component/examples/low_consumption
idf.py set-target ${{ matrix.idf_target }}
idf.py build
- name: Build sample - int32_publisher_custom_transport
shell: bash
run: |
. $IDF_PATH/export.sh
cd micro_ros_espidf_component
make -f libmicroros.mk clean
sed -i 's/DRMW_UXRCE_TRANSPORT=udp/DRMW_UXRCE_TRANSPORT=custom/' colcon.meta
cd examples/int32_publisher_custom_transport
idf.py set-target ${{ matrix.idf_target }}
idf.py build
12 changes: 11 additions & 1 deletion .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,14 @@ jobs:
cd micro_ros_espidf_component/examples/low_consumption
idf.py set-target ${{ matrix.idf_target }}
idf.py build
- name: Build sample - int32_publisher_custom_transport
shell: bash
run: |
. $IDF_PATH/export.sh
cd micro_ros_espidf_component
make -f libmicroros.mk clean
sed -i 's/DRMW_UXRCE_TRANSPORT=udp/DRMW_UXRCE_TRANSPORT=custom/' colcon.meta
cd examples/int32_publisher_custom_transport
idf.py set-target ${{ matrix.idf_target }}
idf.py build
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,14 @@ Dockerfile for this container is provided in the ./docker directory and availabl

## Using serial transport

By default, micro-ROS component uses UDP transport, but is possible to enable UART transport setting the `colcon.meta` like:
By default, micro-ROS component uses UDP transport, but is possible to enable UART transport or any other custom transport setting the `colcon.meta` like:

```json
...
"rmw_microxrcedds": {
"cmake-args": [
...
"-DRMW_UXRCE_TRANSPORT=custom_serial",
"-DRMW_UXRCE_DEFAULT_SERIAL_DEVICE=1",
"-DRMW_UXRCE_TRANSPORT=custom",
...
]
},
Expand Down
4 changes: 3 additions & 1 deletion colcon.meta
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
"cmake-args": [
"-DUCLIENT_PIC=OFF",
"-DUCLIENT_PROFILE_DISCOVERY=ON",
"-DUCLIENT_EXTERNAL_SERIAL=ON",
"-DUCLIENT_PROFILE_UDP=ON",
"-DUCLIENT_PROFILE_CUSTOM_TRANSPORT=ON",
"-DUCLIENT_PROFILE_SERIAL=OFF",
"-DUCLIENT_PROFILE_TCP=OFF"
]
},
Expand Down
3 changes: 3 additions & 0 deletions examples/int32_publisher_custom_transport/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
build
sdkconfig
sdkconfig.old
7 changes: 7 additions & 0 deletions examples/int32_publisher_custom_transport/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.5)

set (EXTRA_COMPONENT_DIRS "./../../.")

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(int32_publisher)

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
idf_component_register(SRCS main.c esp32_serial_transport.c INCLUDE_DIRS "")
15 changes: 15 additions & 0 deletions examples/int32_publisher_custom_transport/main/Kconfig.projbuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
menu "micro-ROS example-app settings"

config MICRO_ROS_APP_STACK
int "Stack the micro-ROS app (Bytes)"
default 15000
help
Stack size in Bytes of the micro-ROS app

config MICRO_ROS_APP_TASK_PRIO
int "Priority of the micro-ROS app"
default 5
help
Priority of micro-ros task higher value means higher priority

endmenu
5 changes: 5 additions & 0 deletions examples/int32_publisher_custom_transport/main/component.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include <uxr/client/transport.h>

#include <driver/uart.h>
#include <driver/gpio.h>

#define UART_TXD (CONFIG_MICROROS_UART_TXD)
#define UART_RXD (CONFIG_MICROROS_UART_RXD)
#define UART_RTS (CONFIG_MICROROS_UART_RTS)
#define UART_CTS (CONFIG_MICROROS_UART_CTS)

// --- micro-ROS Transports ---
#define UART_BUFFER_SIZE (512)

bool esp32_serial_open(struct uxrCustomTransport * transport){
size_t * uart_port = (size_t*) transport->args;

uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
};

if (uart_param_config(*uart_port, &uart_config) == ESP_FAIL) {
return false;
}
if (uart_set_pin(*uart_port, UART_TXD, UART_RXD, UART_RTS, UART_CTS) == ESP_FAIL) {
return false;
}
if (uart_driver_install(*uart_port, UART_BUFFER_SIZE * 2, 0, 0, NULL, 0) == ESP_FAIL) {
return false;
}

return true;
}

bool esp32_serial_close(struct uxrCustomTransport * transport){
size_t * uart_port = (size_t*) transport->args;

return uart_driver_delete(*uart_port) == ESP_OK;
}

size_t esp32_serial_write(struct uxrCustomTransport* transport, const uint8_t * buf, size_t len, uint8_t * err){
size_t * uart_port = (size_t*) transport->args;
const int txBytes = uart_write_bytes(*uart_port, (const char*) buf, len);
return txBytes;
}

size_t esp32_serial_read(struct uxrCustomTransport* transport, uint8_t* buf, size_t len, int timeout, uint8_t* err){
size_t * uart_port = (size_t*) transport->args;
const int rxBytes = uart_read_bytes(*uart_port, buf, len, timeout / portTICK_RATE_MS);
return rxBytes;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2021 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef _MICROROS_CLIENT_ESP32_SERIAL_TRANSPORT_H_
#define _MICROROS_CLIENT_ESP32_SERIAL_TRANSPORT_H_

#ifdef __cplusplus
extern "C"
{
#endif

bool esp32_serial_open(struct uxrCustomTransport * transport);
bool esp32_serial_close(struct uxrCustomTransport * transport);
size_t esp32_serial_write(struct uxrCustomTransport* transport, const uint8_t * buf, size_t len, uint8_t * err);
size_t esp32_serial_read(struct uxrCustomTransport* transport, uint8_t* buf, size_t len, int timeout, uint8_t* err);

#ifdef __cplusplus
}
#endif

#endif //_MICROROS_CLIENT_ESP32_SERIAL_TRANSPORT_H_
114 changes: 114 additions & 0 deletions examples/int32_publisher_custom_transport/main/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_system.h"
#include "driver/uart.h"

#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <std_msgs/msg/int32.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>

#include <rmw_microxrcedds_c/config.h>
#include <rmw_uros/options.h>
#include "esp32_serial_transport.h"

#define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){printf("Failed status on line %d: %d. Aborting.\n",__LINE__,(int)temp_rc);vTaskDelete(NULL);}}
#define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){printf("Failed status on line %d: %d. Continuing.\n",__LINE__,(int)temp_rc);}}

rcl_publisher_t publisher;
std_msgs__msg__Int32 msg;

void timer_callback(rcl_timer_t * timer, int64_t last_call_time)
{
RCLC_UNUSED(last_call_time);
if (timer != NULL) {
RCSOFTCHECK(rcl_publish(&publisher, &msg, NULL));
msg.data++;
}
}

void micro_ros_task(void * arg)
{
rcl_allocator_t allocator = rcl_get_default_allocator();
rclc_support_t support;

rcl_init_options_t init_options = rcl_get_zero_initialized_init_options();
RCCHECK(rcl_init_options_init(&init_options, allocator));
rmw_init_options_t* rmw_options = rcl_init_options_get_rmw_init_options(&init_options);

// Static Agent IP and port can be used instead of autodisvery.
RCCHECK(rmw_uros_options_set_udp_address(CONFIG_MICRO_ROS_AGENT_IP, CONFIG_MICRO_ROS_AGENT_PORT, rmw_options));
//RCCHECK(rmw_uros_discover_agent(rmw_options));

// create init_options
RCCHECK(rclc_support_init_with_options(&support, 0, NULL, &init_options, &allocator));

// create node
rcl_node_t node;
RCCHECK(rclc_node_init_default(&node, "esp32_int32_publisher", "", &support));

// create publisher
RCCHECK(rclc_publisher_init_default(
&publisher,
&node,
ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
"freertos_int32_publisher"));

// create timer,
rcl_timer_t timer;
const unsigned int timer_timeout = 1000;
RCCHECK(rclc_timer_init_default(
&timer,
&support,
RCL_MS_TO_NS(timer_timeout),
timer_callback));

// create executor
rclc_executor_t executor;
RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator));
RCCHECK(rclc_executor_add_timer(&executor, &timer));

msg.data = 0;

while(1){
rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100));
usleep(10000);
}

// free resources
RCCHECK(rcl_publisher_fini(&publisher, &node));
RCCHECK(rcl_node_fini(&node));

vTaskDelete(NULL);
}

void app_main(void)
{
#if defined(RMW_UXRCE_TRANSPORT_CUSTOM)
size_t uart_port = UART_NUM_1;
rmw_uros_set_custom_transport(
true,
(void *) &uart_port,
esp32_serial_open,
esp32_serial_close,
esp32_serial_write,
esp32_serial_read
);
#else
#error micro-ROS transports misconfigured
#endif // RMW_UXRCE_TRANSPORT_CUSTOM

//pin micro-ros task in APP_CPU to make PRO_CPU to deal with wifi:
xTaskCreate(micro_ros_task,
"uros_task",
CONFIG_MICRO_ROS_APP_STACK,
NULL,
CONFIG_MICRO_ROS_APP_TASK_PRIO,
NULL);
}
3 changes: 3 additions & 0 deletions examples/int32_publisher_custom_transport/sdkconfig.defaults
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CONFIG_ESP_MAIN_TASK_STACK_SIZE=3000
CONFIG_ESP_TASK_WDT=n

2 changes: 0 additions & 2 deletions libmicroros.mk
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ $(EXTENSIONS_DIR)/micro_ros_src/src:
touch src/rosidl/rosidl_typesupport_introspection_cpp/COLCON_IGNORE; \
touch src/rclc/rclc_examples/COLCON_IGNORE; \
touch src/rcl/rcl_yaml_param_parser/COLCON_IGNORE; \
cp -f ../serial_transport_external/esp32_serial_transport.c src/Micro-XRCE-DDS-Client/src/c/profile/transport/serial/serial_transport_external.c; \
cp -f ../serial_transport_external/esp32_serial_transport.h src/Micro-XRCE-DDS-Client/include/uxr/client/profile/transport/serial/serial_transport_external.h; \
cp -rf ../extra_packages src/extra_packages || :;


Expand Down

0 comments on commit 8bb5c13

Please sign in to comment.