micro-ROS / micro_ros_setup

Support macros for building micro-ROS-based firmware.
Apache License 2.0
381 stars 137 forks source link

How to set up a custom static library #338

Closed wemaxon closed 3 years ago

wemaxon commented 3 years ago

Issue template

Hello, I have finally managed to get a custom static library to compile following this tutorial and using the example colcon.meta and cmake toolchain provided by the tutorial.

In my application I need to use the serial transport. What are the changes necessary to be made to the colcon.meta file? Where can I find documentation about the cmake-args specified in this file?

I have modified my_custom_colcon.meta file like this:

{
    "names": {
        "tracetools": {
            "cmake-args": [
                "-DTRACETOOLS_DISABLED=ON",
                "-DTRACETOOLS_STATUS_CHECKING_TOOL=OFF"
            ]
        },
        "rosidl_typesupport": {
            "cmake-args": [
                "-DROSIDL_TYPESUPPORT_SINGLE_TYPESUPPORT=ON"
            ]
        },
        "rcl": {
            "cmake-args": [
                "-DBUILD_TESTING=OFF",
                "-DRCL_COMMAND_LINE_ENABLED=OFF",
                "-DRCL_LOGGING_ENABLED=OFF"
            ]
        }, 
        "rcutils": {
            "cmake-args": [
                "-DENABLE_TESTING=OFF",
                "-DRCUTILS_NO_FILESYSTEM=ON",
                "-DRCUTILS_NO_THREAD_SUPPORT=ON",
                "-DRCUTILS_NO_64_ATOMIC=ON",
                "-DRCUTILS_AVOID_DYNAMIC_ALLOCATION=ON"
            ]
        },
        "microxrcedds_client": {
            "cmake-args": [
                "-DUCLIENT_PIC=OFF",
                "-DUCLIENT_PROFILE_UDP=OFF",
                "-DUCLIENT_PROFILE_TCP=OFF",
                "-DUCLIENT_PROFILE_DISCOVERY=OFF",
                "-DUCLIENT_PROFILE_SERIAL=ON",
                "-UCLIENT_PROFILE_STREAM_FRAMING=ON",
                "-DUCLIENT_PROFILE_CUSTOM_TRANSPORT=OFF"
            ]
        },
        "rmw_microxrcedds": {
            "cmake-args": [
                "-DRMW_UXRCE_MAX_NODES=1",
                "-DRMW_UXRCE_MAX_PUBLISHERS=5",
                "-DRMW_UXRCE_MAX_SUBSCRIPTIONS=5",
                "-DRMW_UXRCE_MAX_SERVICES=1",
                "-DRMW_UXRCE_MAX_CLIENTS=1",
                "-DRMW_UXRCE_MAX_HISTORY=4",
                "-DRMW_UXRCE_TRANSPORT=serial"
            ]
        }
    }
}

Unfortunately the compiler throws the following error when trying to compile:

max@max-MacBook:~/microros_ws$ ros2 run micro_ros_setup build_firmware.sh $(pwd)/my_custom_toolchain.cmake $(pwd)/my_custom_colcon.meta
Crosscompiled environment: cleaning path
Building firmware for generate_lib platform generic
Using provided meta: /home/max/microros_ws/my_custom_colcon.meta
Starting >>> tinydir_vendor
Starting >>> rosidl_adapter
Finished <<< rosidl_adapter [1.84s]                                 
Starting >>> rosidl_typesupport_interface
Finished <<< rosidl_typesupport_interface [1.39s]                       
Starting >>> rosidl_parser
Finished <<< rosidl_parser [1.76s]                                       
Starting >>> rosidl_cmake
Finished <<< tinydir_vendor [5.27s]                                   
Starting >>> rcutils
Finished <<< rosidl_cmake [1.69s]                                              
Starting >>> microcdr
Finished <<< microcdr [5.17s]                                      
Starting >>> microxrcedds_client
--- stderr: rcutils                                                
In function 'rcutils_char_array_strncat',
    inlined from 'rcutils_char_array_strcat' at /home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/char_array.c:239:10:
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/char_array.c:224:3: warning: 'strncat' output truncated before terminating nul copying as many bytes from a string as its length [-Wstringop-truncation]
  224 |   strncat(char_array->buffer, src, n);
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/char_array.c: In function 'rcutils_char_array_strcat':
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/char_array.c:239:10: note: length computed here
  239 |   return rcutils_char_array_strncat(char_array, src, strlen(src));
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c: In function 'rcutils_get_cwd':
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c:60:24: warning: unused parameter 'buffer' [-Wunused-parameter]
   60 | rcutils_get_cwd(char * buffer, size_t max_length)
      |                 ~~~~~~~^~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c:60:39: warning: unused parameter 'max_length' [-Wunused-parameter]
   60 | rcutils_get_cwd(char * buffer, size_t max_length)
      |                                ~~~~~~~^~~~~~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c: In function 'rcutils_is_directory':
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c:83:35: warning: unused parameter 'abs_path' [-Wunused-parameter]
   83 | rcutils_is_directory(const char * abs_path)
      |                      ~~~~~~~~~~~~~^~~~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c: In function 'rcutils_is_file':
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c:102:30: warning: unused parameter 'abs_path' [-Wunused-parameter]
  102 | rcutils_is_file(const char * abs_path)
      |                 ~~~~~~~~~~~~~^~~~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c: In function 'rcutils_exists':
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c:121:29: warning: unused parameter 'abs_path' [-Wunused-parameter]
  121 | rcutils_exists(const char * abs_path)
      |                ~~~~~~~~~~~~~^~~~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c: In function 'rcutils_is_readable':
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c:136:34: warning: unused parameter 'abs_path' [-Wunused-parameter]
  136 | rcutils_is_readable(const char * abs_path)
      |                     ~~~~~~~~~~~~~^~~~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c: In function 'rcutils_is_writable':
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c:158:34: warning: unused parameter 'abs_path' [-Wunused-parameter]
  158 | rcutils_is_writable(const char * abs_path)
      |                     ~~~~~~~~~~~~~^~~~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c: In function 'rcutils_is_readable_and_writable':
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c:180:47: warning: unused parameter 'abs_path' [-Wunused-parameter]
  180 | rcutils_is_readable_and_writable(const char * abs_path)
      |                                  ~~~~~~~~~~~~~^~~~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c: In function 'rcutils_mkdir':
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c:257:13: warning: implicit declaration of function 'mkdir' [-Wimplicit-function-declaration]
  257 |   int ret = mkdir(abs_path, 0775);
      |             ^~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c: In function 'rcutils_calculate_directory_size':
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c:267:47: warning: unused parameter 'directory_path' [-Wunused-parameter]
  267 | rcutils_calculate_directory_size(const char * directory_path, rcutils_allocator_t allocator)
      |                                  ~~~~~~~~~~~~~^~~~~~~~~~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c:267:83: warning: unused parameter 'allocator' [-Wunused-parameter]
  267 | late_directory_size(const char * directory_path, rcutils_allocator_t allocator)
      |                                                  ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~

/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c: In function 'rcutils_get_file_size':
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/filesystem.c:325:36: warning: unused parameter 'file_path' [-Wunused-parameter]
  325 | rcutils_get_file_size(const char * file_path)
      |                       ~~~~~~~~~~~~~^~~~~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/logging.c: In function 'rcutils_get_env_var_zero_or_one':
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/logging.c:127:35: warning: unused parameter 'zero_semantic' [-Wunused-parameter]
  127 |   const char * name, const char * zero_semantic,
      |                      ~~~~~~~~~~~~~^~~~~~~~~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/logging.c:128:16: warning: unused parameter 'one_semantic' [-Wunused-parameter]
  128 |   const char * one_semantic)
      |   ~~~~~~~~~~~~~^~~~~~~~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/shared_library.c: In function 'rcutils_load_shared_library':
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/shared_library.c:63:30: warning: unused parameter 'lib' [-Wunused-parameter]
   63 |   rcutils_shared_library_t * lib,
      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/shared_library.c:64:16: warning: unused parameter 'library_path' [-Wunused-parameter]
   64 |   const char * library_path,
      |   ~~~~~~~~~~~~~^~~~~~~~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/shared_library.c:65:23: warning: unused parameter 'allocator' [-Wunused-parameter]
   65 |   rcutils_allocator_t allocator)
      |   ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/shared_library.c: In function 'rcutils_get_symbol':
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/shared_library.c:118:23: warning: implicit declaration of function 'dlsym' [-Wimplicit-function-declaration]
  118 |   void * lib_symbol = dlsym(lib->lib_pointer, symbol_name);
      |                       ^~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/shared_library.c:118:23: warning: initialization of 'void *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/shared_library.c:119:18: warning: implicit declaration of function 'dlerror'; did you mean 'perror'? [-Wimplicit-function-declaration]
  119 |   char * error = dlerror();
      |                  ^~~~~~~
      |                  perror
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/shared_library.c:119:18: warning: initialization of 'char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/shared_library.c: In function 'rcutils_has_symbol':
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/shared_library.c:156:23: warning: initialization of 'void *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
  156 |   void * lib_symbol = dlsym(lib->lib_pointer, symbol_name);
      |                       ^~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/shared_library.c:157:20: warning: comparison between pointer and integer
  157 |   return dlerror() == NULL && lib_symbol != 0;
      |                    ^~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/shared_library.c: In function 'rcutils_unload_shared_library':
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/shared_library.c:175:20: warning: implicit declaration of function 'dlclose'; did you mean 'pclose'? [-Wimplicit-function-declaration]
  175 |   int error_code = dlclose(lib->lib_pointer);
      |                    ^~~~~~~
      |                    pclose
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/shared_library.c: In function 'rcutils_get_platform_library_name':
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/shared_library.c:198:16: warning: unused parameter 'buffer_size' [-Wunused-parameter]
  198 |   unsigned int buffer_size,
      |   ~~~~~~~~~~~~~^~~~~~~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/shared_library.c:199:8: warning: unused parameter 'debug' [-Wunused-parameter]
  199 |   bool debug)
      |        ^
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/time_unix.c:42:4: warning: #warning is a GCC extension
   42 | #  warning no monotonic clock function available
      |    ^~~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/time_unix.c:42:4: warning: #warning no monotonic clock function available [-Wcpp]
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/time_unix.c: In function 'rcutils_system_time_now':
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/time_unix.c:64:3: warning: implicit declaration of function 'clock_gettime' [-Wimplicit-function-declaration]
   64 |   clock_gettime(CLOCK_REALTIME, &timespec_now);
      |   ^~~~~~~~~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/atomic_64bits.c:53:10: warning: mismatch in argument 1 type of built-in function '__atomic_load_8'; expected 'const volatile void *' [-Wbuiltin-declaration-mismatch]
   53 | uint64_t __atomic_load_8(uint64_t *mem, int model) {
      |          ^~~~~~~~~~~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/atomic_64bits.c:62:6: warning: mismatch in argument 1 type of built-in function '__atomic_store_8'; expected 'volatile void *' [-Wbuiltin-declaration-mismatch]
   62 | void __atomic_store_8(uint64_t *mem, uint64_t val, int model) {
      |      ^~~~~~~~~~~~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/atomic_64bits.c:70:10: warning: mismatch in argument 1 type of built-in function '__atomic_exchange_8'; expected 'volatile void *' [-Wbuiltin-declaration-mismatch]
   70 | uint64_t __atomic_exchange_8(uint64_t *mem, uint64_t val, int model) {
      |          ^~~~~~~~~~~~~~~~~~~
/home/max/microros_ws/firmware/mcu_ws/uros/rcutils/src/atomic_64bits.c:80:10: warning: mismatch in argument 1 type of built-in function '__atomic_fetch_add_8'; expected 'volatile void *' [-Wbuiltin-declaration-mismatch]
   80 | uint64_t __atomic_fetch_add_8(uint64_t *mem, uint64_t val, int model) {
      |          ^~~~~~~~~~~~~~~~~~~~
---
Finished <<< rcutils [7.32s]
Starting >>> rosidl_runtime_c
--- stderr: rosidl_runtime_c                                                  
CMake Warning at /home/max/microros_ws/firmware/mcu_ws/install/share/rcutils/cmake/ament_cmake_export_libraries-extras.cmake:116 (message):
  Package 'rcutils' exports library 'dl' which couldn't be found
Call Stack (most recent call first):
  /home/max/microros_ws/firmware/mcu_ws/install/share/rcutils/cmake/rcutilsConfig.cmake:41 (include)
  CMakeLists.txt:15 (find_package)

---
Finished <<< rosidl_runtime_c [3.72s]
Starting >>> rmw
--- stderr: microxrcedds_client                                               
/home/max/microros_ws/firmware/mcu_ws/eProsima/Micro-XRCE-DDS-Client/src/c/util/time.c: In function 'uxr_nanos':
/home/max/microros_ws/firmware/mcu_ws/eProsima/Micro-XRCE-DDS-Client/src/c/util/time.c:60:5: warning: implicit declaration of function 'clock_gettime' [-Wimplicit-function-declaration]
   60 |     clock_gettime(CLOCK_REALTIME, &ts);
      |     ^~~~~~~~~~~~~
In file included from /home/max/microros_ws/firmware/mcu_ws/eProsima/Micro-XRCE-DDS-Client/include/uxr/client/transport.h:46,
                 from /home/max/microros_ws/firmware/mcu_ws/eProsima/Micro-XRCE-DDS-Client/include/uxr/client/util/ping.h:28,
                 from /home/max/microros_ws/firmware/mcu_ws/eProsima/Micro-XRCE-DDS-Client/src/c/util/ping.c:1:
/home/max/microros_ws/firmware/mcu_ws/eProsima/Micro-XRCE-DDS-Client/include/uxr/client/profile/transport/serial/serial_transport.h:39:30: error: field 'platform' has incomplete type
   39 |     struct uxrSerialPlatform platform;
      |                              ^~~~~~~~
make[2]: *** [CMakeFiles/microxrcedds_client.dir/build.make:261: CMakeFiles/microxrcedds_client.dir/src/c/util/ping.c.obj] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [CMakeFiles/Makefile2:79: CMakeFiles/microxrcedds_client.dir/all] Error 2
make: *** [Makefile:133: all] Error 2
---
Failed   <<< microxrcedds_client [5.45s, exited with code 2]
Aborted  <<< rmw [1.88s]                             

Summary: 8 packages finished [19.4s]
  1 package failed: microxrcedds_client
  1 package aborted: rmw
  4 packages had stderr output: microxrcedds_client rcutils rmw rosidl_runtime_c
  50 packages not processed

I am aware, that I need to implement the serial_transport hardware handler functions at some point, but I thought this would be done after compiling the static library, when including it in my project. Am I wrong?

Thanks again for your help

pablogs9 commented 3 years ago

In the colcon.meta try to change the transports to:

                "-DUCLIENT_PROFILE_SERIAL=OFF",
                "-UCLIENT_PROFILE_STREAM_FRAMING=ON",
                "-DUCLIENT_PROFILE_CUSTOM_TRANSPORT=ON"
wemaxon commented 3 years ago

Hey @pablogs9 ,

if I change the colcon.meta the way you proposed and additionally change this line accordingly: "-DRMW_UXRCE_TRANSPORT=serial" the static library will compile succesfully.

However I'd like to use the UART on my microcontroller as transport, I dont want to set up a custom transport. Or this the way to go and I should try to set up a custom transport using the UART Hardware?

pablogs9 commented 3 years ago

My recommendation is that you set custom transport and the you write your UART transports outside the micro-ROS library. Check this and this.

wemaxon commented 3 years ago

Ok, thanks for your input, it helps a lot!

When I add the library to my Mbed Studio project folder I get a compilation error. The error message can be seen below. This happens even without including any micro-ros headers in my code. I believe the Mbed Studio Toolchain is set up in way, in which it tries to compile everything and but only link the necessary files.

Can this error occur because of a static library created incorrectly? Or is it because the toolchain is trying to compile files with extern code that needs implementation?

Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__String__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/actionlib_msgs/msg/detail/goal_id__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__String__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/actionlib_msgs/msg/detail/goal_id__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__String__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/composition_interfaces/srv/detail/list_nodes__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__String__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/composition_interfaces/srv/detail/list_nodes__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__uint64__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/composition_interfaces/srv/detail/list_nodes__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__uint64__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/composition_interfaces/srv/detail/list_nodes__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__int32__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/action/detail/fibonacci__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__int32__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/action/detail/fibonacci__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__octet__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/byte_multi_array__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__octet__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/byte_multi_array__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__float__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/float32_multi_array__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__float__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/float32_multi_array__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__double__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/float64_multi_array__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__double__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/float64_multi_array__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__int16__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/int16_multi_array__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__int16__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/int16_multi_array__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__int64__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/int64_multi_array__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__int64__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/int64_multi_array__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__int8__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/int8_multi_array__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__int8__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/int8_multi_array__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__uint16__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/u_int16_multi_array__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__uint16__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/u_int16_multi_array__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__uint32__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/u_int32_multi_array__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__uint32__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/u_int32_multi_array__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__uint8__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/u_int8_multi_array__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__uint8__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/u_int8_multi_array__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__U16String__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/w_string__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__U16String__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/w_string__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__boolean__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/rcl_interfaces/msg/detail/parameter_value__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__boolean__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/rcl_interfaces/msg/detail/parameter_value__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__String__assign (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/test_msgs/msg/detail/arrays__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__U16String__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/test_msgs/msg/detail/w_strings__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__U16String__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/test_msgs/msg/detail/w_strings__functions.o).
[Error] @0,0: L6218E: Undefined symbol rosidl_runtime_c__U16String__assign (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/test_msgs/msg/detail/w_strings__functions.o).
Warning: L3912W: Option 'legacyalign' is deprecated.
Error: L6218E: Undefined symbol rosidl_runtime_c__String__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/actionlib_msgs/msg/detail/goal_id__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__String__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/actionlib_msgs/msg/detail/goal_id__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__String__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/composition_interfaces/srv/detail/list_nodes__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__String__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/composition_interfaces/srv/detail/list_nodes__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__uint64__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/composition_interfaces/srv/detail/list_nodes__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__uint64__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/composition_interfaces/srv/detail/list_nodes__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__int32__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/action/detail/fibonacci__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__int32__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/action/detail/fibonacci__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__octet__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/byte_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__octet__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/byte_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__float__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/float32_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__float__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/float32_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__double__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/float64_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__double__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/float64_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__int16__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/int16_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__int16__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/int16_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__int64__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/int64_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__int64__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/int64_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__int8__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/int8_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__int8__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/int8_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__uint16__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/u_int16_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__uint16__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/u_int16_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__uint32__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/u_int32_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__uint32__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/u_int32_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__uint8__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/u_int8_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__uint8__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/u_int8_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__U16String__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/w_string__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__U16String__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/w_string__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__boolean__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/rcl_interfaces/msg/detail/parameter_value__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__boolean__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/rcl_interfaces/msg/detail/parameter_value__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__String__assign (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/test_msgs/msg/detail/arrays__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__U16String__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/test_msgs/msg/detail/w_strings__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__U16String__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/test_msgs/msg/detail/w_strings__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__U16String__assign (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/test_msgs/msg/detail/w_strings__functions.o).
Finished: 0 information, 1 warning and 34 error messages.
[ERROR] Warning: L3912W: Option 'legacyalign' is deprecated.
Error: L6218E: Undefined symbol rosidl_runtime_c__String__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/actionlib_msgs/msg/detail/goal_id__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__String__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/actionlib_msgs/msg/detail/goal_id__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__String__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/composition_interfaces/srv/detail/list_nodes__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__String__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/composition_interfaces/srv/detail/list_nodes__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__uint64__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/composition_interfaces/srv/detail/list_nodes__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__uint64__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/composition_interfaces/srv/detail/list_nodes__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__int32__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/action/detail/fibonacci__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__int32__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/action/detail/fibonacci__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__octet__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/byte_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__octet__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/byte_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__float__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/float32_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__float__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/float32_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__double__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/float64_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__double__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/float64_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__int16__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/int16_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__int16__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/int16_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__int64__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/int64_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__int64__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/int64_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__int8__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/int8_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__int8__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/int8_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__uint16__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/u_int16_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__uint16__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/u_int16_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__uint32__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/u_int32_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__uint32__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/u_int32_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__uint8__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/u_int8_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__uint8__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/u_int8_multi_array__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__U16String__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/w_string__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__U16String__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/example_interfaces/msg/detail/w_string__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__boolean__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/rcl_interfaces/msg/detail/parameter_value__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__boolean__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/rcl_interfaces/msg/detail/parameter_value__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__String__assign (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/test_msgs/msg/detail/arrays__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__U16String__Sequence__fini (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/test_msgs/msg/detail/w_strings__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__U16String__Sequence__init (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/test_msgs/msg/detail/w_strings__functions.o).
Error: L6218E: Undefined symbol rosidl_runtime_c__U16String__assign (referred from BUILD/SFE_ARTEMIS_THING_PLUS/ARMC6/micro_ros/include/test_msgs/msg/detail/w_strings__functions.o).
pablogs9 commented 3 years ago

You can check if those symbols exist in your static library doing nm libmicroros.a, if they exist in the library you are having linking problems.

wemaxon commented 3 years ago

Hey @pablogs9, thanks again for your support.

I have switched the IDE and Toolchain again and am back to Arduino now. I added my precompiled static library and implemented the transports and clock_gettime function exactly the way done in the micro_ros_arduino build.

This works great, I managed to establish a connection to the Micro XRCE-Agent and exchange data! However I am still having one minor issue: The created timer won't call the timer_callback function. Publishing to a topic works when calling rcl_publish() but somehow the timer, which I created based on this example, is not being called at all.

This is the the timer initalization:

#include <micro_ros.h> //Empty header file needed for Arduino toolchain to work

#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_microros/rmw_microros.h>

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

// --- micro-ROS Transports ---
extern "C" bool arduino_transport_open(struct uxrCustomTransport * transport);
extern "C" bool arduino_transport_close(struct uxrCustomTransport * transport);
extern "C" size_t arduino_transport_write(struct uxrCustomTransport* transport, const uint8_t * buf, size_t len, uint8_t * err);
extern "C" size_t arduino_transport_read(struct uxrCustomTransport* transport, uint8_t* buf, size_t len, int timeout, uint8_t* err);

// --- micro-ROS App ---
rcl_publisher_t publisher;
std_msgs__msg__Int32 msg;
rclc_executor_t executor;

void timer_callback(rcl_timer_t * timer, int64_t last_call_time) //<<<----- Never being reached
{
  Serial_DB.printf("[micro-ros]msg published \n");

  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)

  RCLC_UNUSED(last_call_time);
  if (timer != NULL) {
    RCSOFTCHECK(rcl_publish(&publisher, &msg, NULL));
    msg.data++;
  }
  digitalWrite(LED_BUILTIN, LOW);   // turn the LED on (HIGH is the voltage level)

}

void micro_ros_init()
{
  rmw_uros_set_custom_transport(
        true,
        NULL,
        arduino_transport_open,
        arduino_transport_close,
        arduino_transport_write,
        arduino_transport_read
    );

  Serial_DB.printf("[micro-ros]custom Transport set \n");

  rcl_allocator_t allocator = rcl_get_default_allocator();
  rclc_support_t support;
  Serial_DB.printf("[micro-ros]rcl_allocator and rclc_support created \n");

  // create init_options
  RCCHECK(rclc_support_init(&support, 0, NULL, &allocator));
  Serial_DB.printf("[micro-ros]rclc_support init \n");

  // create node
  rcl_node_t node;
  RCCHECK(rclc_node_init_default(&node, "mbed_node", "", &support));
  Serial_DB.printf("[micro-ros]rcl_node created and initialised \n");

  // create publisher
  RCCHECK(rclc_publisher_init_default(
    &publisher,
    &node,
    ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
    "test_int32_publisher"));
  Serial_DB.printf("[micro-ros]rclc_publisher initialised \n");

  // 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));
  Serial_DB.printf("[micro-ros]rcl_timer created and initialised \n");

  // create executor
  RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator));
  RCCHECK(rclc_executor_add_timer(&executor, &timer));
  Serial_DB.printf("[micro-ros]rcl_exectutor created and added to timer \n");

  msg.data = 0;
}

void micro_ros_spin()
{
  rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100));
}

And the transports.cpp:

 /* 
 *  --- micro-ROS Timing and transports ---
 *  
 *  From https://github.com/micro-ROS/micro_ros_arduino, under Apache-2.0 License
 */

#include <Arduino.h>

extern "C"
{
  #include <stdio.h>
  #include <stdbool.h>
  #include <sys/time.h>

  #include "config.h"

  int clock_gettime(clockid_t unused, struct timespec *tp) __attribute__ ((weak));
  bool arduino_transport_open(struct uxrCustomTransport * transport) __attribute__ ((weak));
  bool arduino_transport_close(struct uxrCustomTransport * transport) __attribute__ ((weak));
  size_t arduino_transport_write(struct uxrCustomTransport * transport, uint8_t *buf, size_t len, uint8_t *errcode) __attribute__ ((weak));
  size_t arduino_transport_read(struct uxrCustomTransport * transport, uint8_t *buf, size_t len, int timeout, uint8_t *errcode) __attribute__ ((weak));

  #define micro_rollover_useconds 4294967295

  int clock_gettime(clockid_t unused, struct timespec *tp)
  {
    (void)unused;
    static uint32_t rollover = 0;
    static uint64_t last_measure = 0;

    uint64_t m = micros();
    tp->tv_sec = m / 1000000;
    tp->tv_nsec = (m % 1000000) * 1000;

    // Rollover handling
    rollover += (m < last_measure) ? 1 : 0;
    uint64_t rollover_extra_us = rollover * micro_rollover_useconds;
    tp->tv_sec += rollover_extra_us / 1000000;
    tp->tv_nsec += (rollover_extra_us % 1000000) * 1000;
    last_measure = m;

    return 0;
  }

  bool arduino_transport_open(struct uxrCustomTransport * transport)
  {
    Serial_CC.begin(115200);
    return true;
  }

  bool arduino_transport_close(struct uxrCustomTransport * transport)
  {
    Serial_CC.end();
    return true;
  }

  size_t arduino_transport_write(struct uxrCustomTransport * transport, uint8_t *buf, size_t len, uint8_t *errcode)
  {
    (void)errcode;
    size_t sent = Serial_CC.write(buf, len);
    return sent;
  }

  size_t arduino_transport_read(struct uxrCustomTransport * transport, uint8_t *buf, size_t len, int timeout, uint8_t *errcode)
  {
    (void)errcode;
    Serial_CC.setTimeout(timeout);
    return Serial_CC.readBytes((char *)buf, len);
  }
}
pablogs9 commented 3 years ago

Can you verify that clock_gettime() works as expected, by for example printing the obtained value in a loop and checking that it correctly measure the time?

wemaxon commented 3 years ago

Hello @pablogs9,

apologies for being absent this long. I didnt focus on getting the timer to work, because it wasnt really needed in my project, but I am having more problems now and I think they might be related. Somehow my subscription callback functions won't be called when publishing to the subscribed topic.

I modified the clock_gettime() function to print the obtained value:

  int clock_gettime(clockid_t unused, struct timespec *tp)
  {
    (void)unused;
    static uint32_t rollover = 0;
    static uint64_t last_measure = 0;

    uint64_t m = micros();
    tp->tv_sec = m / 1000000;
    tp->tv_nsec = (m % 1000000) * 1000;

    // Rollover handling
    rollover += (m < last_measure) ? 1 : 0;
    uint64_t rollover_extra_us = rollover * micro_rollover_useconds;
    tp->tv_sec += rollover_extra_us / 1000000;
    tp->tv_nsec += (rollover_extra_us % 1000000) * 1000;
    last_measure = m;

    #ifdef Serial_DB
    Serial_DB.printf("[micro-ros]clock_gettime %d \n", tp->tv_nsec );
    #endif //Serial_DB

    return 0;
  }

This is the printed debugging result:

[MAIN]Application started<\r><\n>
[micro-ros]custom Transport set <\n>
[micro-ros]rcl_allocator and rclc_support created <\n>
[micro-ros]clock_gettime 9734000 <\n>
[micro-ros]clock_gettime 12827000 <\n>
[micro-ros]clock_gettime 18717000 <\n>
[micro-ros]clock_gettime 308019000 <\n>
[micro-ros]rclc_support init <\n>
[micro-ros]clock_gettime 318005000 <\n>
[micro-ros]clock_gettime 321192000 <\n>
[micro-ros]clock_gettime 341588000 <\n>
[micro-ros]rcl_node created and initialised <\n>
[micro-ros]clock_gettime 358594000 <\n>
[micro-ros]clock_gettime 361786000 <\n>
[micro-ros]clock_gettime 365351000 <\n>
[micro-ros]clock_gettime 368585000 <\n>
[micro-ros]clock_gettime 371772000 <\n>
[micro-ros]clock_gettime 375270000 <\n>
[micro-ros]clock_gettime 382815000 <\n>
[micro-ros]clock_gettime 386014000 <\n>
[micro-ros]clock_gettime 389578000 <\n>
[micro-ros]clock_gettime 392811000 <\n>
[micro-ros]clock_gettime 395994000 <\n>
[micro-ros]clock_gettime 399493000 <\n>
[micro-ros]clock_gettime 408090000 <\n>
[micro-ros]clock_gettime 411275000 <\n>
[micro-ros]clock_gettime 414876000 <\n>
[micro-ros]clock_gettime 418152000 <\n>
[micro-ros]clock_gettime 421336000 <\n>
[micro-ros]clock_gettime 424840000 <\n>
[micro-ros]clock_gettime 440444000 <\n>
[micro-ros]clock_gettime 443638000 <\n>
[micro-ros]clock_gettime 447207000 <\n>
[micro-ros]clock_gettime 450439000 <\n>
[micro-ros]clock_gettime 453628000 <\n>
[micro-ros]clock_gettime 457131000 <\n>
[micro-ros]clock_gettime 464677000 <\n>
[micro-ros]clock_gettime 467864000 <\n>
[micro-ros]clock_gettime 471429000 <\n>
[micro-ros]clock_gettime 474658000 <\n>
[micro-ros]clock_gettime 477845000 <\n>
[micro-ros]clock_gettime 481344000 <\n>
[micro-ros]clock_gettime 489932000 <\n>
[micro-ros]clock_gettime 493117000 <\n>
[micro-ros]clock_gettime 496715000 <\n>
[micro-ros]clock_gettime 500008000 <\n>
[micro-ros]clock_gettime 503192000 <\n>
[micro-ros]clock_gettime 506696000 <\n>
[micro-ros]clock_gettime 521221000 <\n>
[micro-ros]clock_gettime 524424000 <\n>
[micro-ros]clock_gettime 528028000 <\n>
[micro-ros]clock_gettime 531261000 <\n>
[micro-ros]clock_gettime 534444000 <\n>
[micro-ros]clock_gettime 537954000 <\n>
[micro-ros]clock_gettime 545497000 <\n>
[micro-ros]clock_gettime 548704000 <\n>
[micro-ros]clock_gettime 552267000 <\n>
[micro-ros]clock_gettime 555496000 <\n>
[micro-ros]clock_gettime 558683000 <\n>
[micro-ros]clock_gettime 562182000 <\n>
[micro-ros]clock_gettime 570770000 <\n>
[micro-ros]clock_gettime 573956000 <\n>
[micro-ros]clock_gettime 577551000 <\n>
[micro-ros]clock_gettime 580831000 <\n>
[micro-ros]clock_gettime 584015000 <\n>
[micro-ros]clock_gettime 587514000 <\n>
[micro-ros]rclc_publisher initialised <\n>
[micro-ros]clock_gettime 595787000 <\n>
[micro-ros]rcl_timer created and initialised <\n>
[micro-ros]rcl_exectutor created <\n>
[MAIN] Entering Loop <\n>
[micro-ros]start spinning <\n>
[micro-ros]returned from spinning <\n>
[micro-ros]start spinning <\n>
[micro-ros]returned from spinning <\n>
[micro-ros]start spinning <\n>
[micro-ros]returned from spinning <\n>
[micro-ros]start spinning <\n>
[micro-ros]returned from spinning <\n>
[micro-ros]start spinning <\n>
[micro-ros]returned from spinning <\n>
[micro-ros]start spinning <\n>
[micro-ros]returned from spinning <\n>
[micro-ros]start spinning <\n>
[micro-ros]returned from spinning <\n>
[micro-ros]start spinning <\n>
[micro-ros]returned from spinning <\n>
[micro-ros]start spinning <\n>
[micro-ros]returned from spinning <\n>
[micro-ros]start spinning <\n>
[micro-ros]returned from spinning <\n>
[micro-ros]start spinning <\n>
[micro-ros]returned from spinning <\n>

I think the clock_gettime() function is working correctly but is not being called anymore after the micro ros setup functions are done. This happens although I am calling rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100)); or rclc_executor_spin(&executor); in the endless loop. With some debug output I can even see microcontroller exiting the rclc_executor_spin(&executor); function, which should run indefinitely ?!

This is my micro-ros integration (micro_ros_handler.cpp):

#include "micro_ros_handler.h"

#include "config.h"

#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>
#include <rmw_microros/rmw_microros.h>

#include <std_msgs/msg/int32.h>
#include <px4_msgs/msg/vehicle_local_position.h>

#ifdef Serial_DB
  #define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){ Serial_DB.printf("[micro-ros]Failed status on line %d: %d. Aborting.\n",__LINE__,(int)temp_rc);  while(1){};}}
  #define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){  Serial_DB.printf("[micro-ros]Failed status on line %d: %d. Continuing.\n",__LINE__,(int)temp_rc); }}
#else
  #define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){ while(1){};}}
  #define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}}
#endif //Serial_DB

// --- micro-ROS Transports ---
extern "C" bool arduino_transport_open(struct uxrCustomTransport * transport);
extern "C" bool arduino_transport_close(struct uxrCustomTransport * transport);
extern "C" size_t arduino_transport_write(struct uxrCustomTransport* transport, const uint8_t * buf, size_t len, uint8_t * err);
extern "C" size_t arduino_transport_read(struct uxrCustomTransport* transport, uint8_t* buf, size_t len, int timeout, uint8_t* err);

// --- micro-ROS App ---
rclc_executor_t executor;

rcl_publisher_t publisherPositionSetpoint;
rcl_subscription_t subscriberLocalPosition;
rcl_subscription_t subscriberTest;

std_msgs__msg__Int32 test_msg;
std_msgs__msg__Int32 test_msg_two;
px4_msgs__msg__VehicleLocalPosition LocalPosition;

void timer_callback(rcl_timer_t * timer, int64_t last_call_time)
{
  #ifdef Serial_DB
  Serial_DB.printf("[micro-ros]timer callback \n");
  #endif //Serial_DB

  /*
  RCLC_UNUSED(last_call_time);
  if (timer != NULL) {
    RCSOFTCHECK(rcl_publish(&publisherPositionSetpoint, &msg, NULL));
    msg.data++;
  }
  */
}

void subscription_callback(const void * msgin)
{
  #ifdef Serial_DB
  Serial_DB.printf("[micro-ros]subscription callback \n");
  #endif //Serial_DB
}

void micro_ros_init()
{
  /*
   * set custom transport
   */
  rmw_uros_set_custom_transport(
        true,
        NULL,
        arduino_transport_open,
        arduino_transport_close,
        arduino_transport_write,
        arduino_transport_read
    );

  #ifdef Serial_DB
  Serial_DB.printf("[micro-ros]custom Transport set \n");
  #endif //Serial_DB

  /*
   * create rcl_allocator and rclc_support
   */  
  rcl_allocator_t allocator = rcl_get_default_allocator();
  rclc_support_t support;

  #ifdef Serial_DB
  Serial_DB.printf("[micro-ros]rcl_allocator and rclc_support created \n");
  #endif //Serial_DB

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

  #ifdef Serial_DB
  Serial_DB.printf("[micro-ros]rclc_support init \n");
  #endif //Serial_DB

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

  #ifdef Serial_DB
  Serial_DB.printf("[micro-ros]rcl_node created and initialised \n");
  #endif //Serial_DB

  /*
   * create publisher and subscribers
   */
  RCCHECK(rclc_publisher_init_default(&publisherPositionSetpoint, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32), "PositionSetpoint"));

  subscriberLocalPosition = rcl_get_zero_initialized_subscription();
  RCCHECK(rclc_subscription_init_default(&subscriberLocalPosition, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(px4_msgs, msg, VehicleLocalPosition), "/fmu/vehicle_local_position/out"));

  subscriberTest = rcl_get_zero_initialized_subscription();
  RCCHECK(rclc_subscription_init_default(&subscriberTest, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32), "test_msg_two"));

  #ifdef Serial_DB
  Serial_DB.printf("[micro-ros]rclc_publisher initialised \n");
  #endif //Serial_DB

  /*
   * 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));

  #ifdef Serial_DB
  Serial_DB.printf("[micro-ros]rcl_timer created and initialised \n");
  #endif //Serial_DB

  /*
   * create executor
   */
  executor = rclc_executor_get_zero_initialized_executor();
  RCCHECK(rclc_executor_init(&executor, &support.context, EXECUTOR_NUM_HANDLES, &allocator));
  RCCHECK(rclc_executor_add_timer(&executor, &timer));

  px4_msgs__msg__VehicleLocalPosition__init(&LocalPosition);
  RCCHECK(rclc_executor_add_subscription(&executor, &subscriberLocalPosition, &LocalPosition, &subscription_callback, ON_NEW_DATA));

  std_msgs__msg__Int32__init(&test_msg_two);
  RCCHECK(rclc_executor_add_subscription(&executor, &subscriberTest, &test_msg_two, &subscription_callback, ALWAYS));

  #ifdef Serial_DB
  Serial_DB.printf("[micro-ros]rcl_exectutor created \n");
  #endif //Serial_DB

  test_msg.data = 0;
}

void micro_ros_spin()
{
  #ifdef Serial_DB
  Serial_DB.printf("[micro-ros]start spinning \n");
  #endif //Serial_DB

  //rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100));
  rclc_executor_spin(&executor);

  #ifdef Serial_DB
  Serial_DB.printf("[micro-ros]returned from spinning \n");
  #endif //Serial_DB

}

void micro_ros_publish()
{
    RCSOFTCHECK(rcl_publish(&publisherPositionSetpoint, &test_msg, NULL));

    #ifdef Serial_DB
    Serial_DB.printf("[micro-ros]msg published \n");
    #endif //Serial_DB
}

I'd be grateful for any input on how to solve this, thanks!

My Firmware: SFE_LoRa_Module_Firmware.zip

pablogs9 commented 3 years ago

You are creating multiple variables in micro_ros_init() stack space, for example rclc_support_t support; rcl_node_t node; or rcl_timer_t timer;. They wont exist when you call micro_ros_spin() outside of that function.

Make those variables global or static.

wemaxon commented 3 years ago

This makes sense. The timers and subscriptions are working now. Thank you @pablogs9