Test connection with micro ROS agent

Hello! I am trying to test the connection with the micro ROS agent from my Teensy board.
Setup

Computer: ROS2 Foxy / Ubuntu 20.04
Board: Teensy 3.1 / Arduino IDE 1.8.13 / Teensyduino 1.53

Desired behavior
I would like to check the connection to the micro ROS agent every loop. Depending on whether the board is connected to the agent at the beginning of each loop, different functions should be executed. I also switch off the board LED if not connected (and switch it back on otherwise). To test the connection, I tried something like this: auto-discovering agent demo code. My code looks like this:
bool connected_to_micro_ROS_agent = false;

rmw_init_options_t* rmw_options;
rclc_executor_t executor;
rclc_support_t support;
rcl_node_t node;
unsigned int rcl_wait_timeout = 100;   // in ms

void checkConnectionMicroROSAgent(){
  if (rmw_uros_discover_agent(rmw_options) != RCL_RET_OK) {
    // Turn LED off if not connected
    connected_to_micro_ROS_agent = false;
    digitalWrite(LED_PIN, LOW);
  }else{
    // Turn LED on if connected
    connected_to_micro_ROS_agent = true;
    digitalWrite(LED_PIN, HIGH);
  } return;
}

void setup(){
  // Turn LED on during init
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);

  // Init ROS
  // options
  rclc_support_init(&support, 0, NULL, &rcl_get_default_allocator());
  rmw_options = rcl_init_options_get_rmw_init_options(&rcl_get_zero_initialized_init_options());
  //  node
  node = rcl_get_zero_initialized_node();
  rclc_node_init_default(&node, "micro_ros_teensy_node", "", &support);
  // executor
  executor = rclc_executor_get_zero_initialized_executor();
  rclc_executor_init(&executor, &support.context, 1, &rcl_get_default_allocator());
  rclc_executor_set_timeout(&executor, RCL_MS_TO_NS(rcl_wait_timeout));

   // Init publishers, subscribers, etc...
   // [...]
}

void loop(){
   checkConnectionMicroROSAgent();

    if (!connected_to_micro_ROS_agent){
     // functions to execute if no connection
    // [...]
   } else {
     // functions to execute if connection
     // [...]
   }

   // functions to execute anyway
   // [...]

}

Actual behavior
The board LED is switched off right after initialization, and never switched on again. So it seems that there is no agent detected.
However, I have an agent running. Plus, if there are publishers in the section "functions to execute if no connection" or "function to execute anyway", the topics are well advertised.
I guess the problem is coming from the connection test, or the rmw_options initialization (may be both...). Could you help me out with this please?
Edit: If the agent is killed with the Teensy application is looping, the LED stays off. If the agent is not running when the application is firstly launched, the LED stays on (and switches off once the agent is launched). Does the application wait for an agent to enter void loop()? If so, is there a way to avoid this behavior?

Hello @anaelle-sw, the rmw_uros_discover_agent() function is intended to discover the IP address and UDP port of the micro-ROS Agent and connect to it when you are networking transports. This discovery uses UDP broadcast messages, but this feature has no sense in serial transports.
If you want to know if your board is actually connected to the micro-ROS Agent:

In the setup rclc_support_init() and all the entities creation functions return RCL_RET_OK (type rcl_ret_t) if they have successfully talked with the agent, so you can infer that the agent is there and working.
In the loop, the function rclc_executor_spin_some() should return something different than RCL_RET_OK when the Agent does not respond to the client.

Right now I'm not completely sure if in serial transport this will work like this and of course, rclc_executor_spin_some can return a not OK status for other different causes. So I'm going to prepare a function inside the direct RMW API that just check the agent availability, I think that is useful.
Let me know if checking the return code of the rclc_executor_spin_some fits your requirements. I will come back here later with the new function pull request.

Thanks for your quick answer. Sorry, I didn't realise the rmw_uros_discover_agent() was not meant for serial communication.
Well, checking the return code of rclc_executor_spin_some() could be useful in some cases. Here we need to check if there is a micro-ROS agent running (and even more, if it is connected to the board).
Our application has features that must always be running, even if there is no connection to the agent, and even if rclc_executor_spin_some returns error status. To maximaze the reliability, it would be nice if we could differentiate these 3 cases:

the agent is /is not available,
the board is / is not connected to the agent,
the executor is / is not spinning.

So I'm going to prepare a function inside the direct RMW API that just check the agent availability, I think that is useful.

So yes, such a function would be really useful in our use case. Thanks a lot!

Ok, I got your question now. No, calling to rclc_support_init should not block your operation forever. If there's no agent present this function will return at some point with a non-RCL_RET_OK code.
Checking if micro-ROS has been able to init sessions with the Agent
If this happens, you should no try to init anything else because the behavior is undefined. Entities always should be created if RCLC is correctly inited.
Regarding the time this function takes to determine that it is impossible to connect with an agent you have a couple of configuration, so maybe you can try a .meta with:
        "microxrcedds_client": {
            "cmake-args": [
...
                "-DUCLIENT_MAX_SESSION_CONNECTION_ATTEMPTS=3",
                "-DUCLIENT_MIN_SESSION_CONNECTION_INTERVAL=25",
...
            ]
        },

Remember that DUCLIENT_MIN_SESSION_CONNECTION_INTERVAL is in milliseconds.
Checking if micro-ROS has communication with the agent
We are preparing this: https://github.com/micro-ROS/rmw-microxrcedds/pull/86, with this function you will be able to check if micro-ROS is connected:

If you haven't done a successful rclc_support_init this will return RMW_RET_ERROR
If you have done a successful rclc_support_init but the agent is disconnected or is not responding because of any cause, it will return RMW_RET_ERROR.
Just in the case that the agent answers to the client to a tiny XRCE message named SYNC, it will return RMW_RET_OK in this case you know that the agent is ready.

@jamoralp has merged it just now. So update your micro-ROS library with this new feature and let me know if this is the feature that you are looking for. If not, let me know and we can do improvements.
Thanks for your feedback!

This new feature works well for me. With the same code as above, and having rmw_uros_discover_agent() replaced by rmw_uros_check_agent_status(), the LED is switched off when the micro-ROS agent is killed. Nice feature, thanks!
But the application still seems to not enter the loop() if no agent is firstly launched, since the LED stays on for longer than the default 3*25 ms connection attempts. I also tried this while following your instructions about checking RCLC initialization when creating every entities. The same behavior happens.
I will test this with set up DUCLIENT_MIN_SESSION_CONNECTION_INTERVAL and DUCLIENT_MAX_SESSION_CONNECTION_ATTEMPTS options next week, and will keep you informed whether it is better.

I'm going to do a couple of tests, but I have seen that the connection time attempts are implemented as a log function. Check here. The waiting time of the connection is always doubled so in the case of 3 retries and 23 ms it should fail after (25 + 50 + 100) ms, let me do this test here.
Maybe we should restructure this. I'm coming back in a while with some answers.

Hello @anaelle-sw, I have uploaded a reconnection example. Here the board will work, it will connect with the agent when available, and handles disconnections and reconnections. Check here
Remember to change the DUCLIENT_MIN_SESSION_CONNECTION_INTERVAL and DUCLIENT_MAX_SESSION_CONNECTION_ATTEMPTS. The total time the XRCE library is trying to connect with the agent can be calculated:
# This is Python3
DUCLIENT_MIN_SESSION_CONNECTION_INTERVAL = 50
DUCLIENT_MAX_SESSION_CONNECTION_ATTEMPTS = 3
max_time_ms = sum([ DUCLIENT_MIN_SESSION_CONNECTION_INTERVAL * (2**x) for x in range(DUCLIENT_MAX_SESSION_CONNECTION_ATTEMPTS) ])

This way your connection time is bounded.
The closing time is also bounded and the client will be trying to destroy each entity for a second. Of course in the case that there is no agent available, it will wait for the whole second. So it should take some seconds to return. This is RMW implementation and we can modify it, maybe we want to destroy entities without confirmation or maybe we can add a parameter to set the max time it should wait until destroying confirmation.
Thoughs?

Hi! Sorry, it took me a while to do all the tests I wanted to.
Very nice re-connection example. I tried to adapt it for our application. But I still have trouble to make it work, as we would rather not use timers.
Here's my problem. Instead of checking for micro ros agent state in a timer, it would be checked in the void loop. So I slightly modified your example. I added this function (uRos_available being a global variable):
void checkURosAvailability() {
  if (rmw_uros_check_agent_status(10) == RMW_RET_OK) {
    uRos_available = true;
  }else{
    uRos_available = false;
  }
}

the timer callback becomes:
void timer_callback(rcl_timer_t * timer, int64_t last_call_time)
{
  if (uRos_available) {
    rcl_publish(&publisher, &msg, NULL);
    msg.data++;
  }else{
    micro_ros_should_fini = true;
  }
}

and my loop looks like this:
void loop(){
  checkURosAvailability();
  if(uRos_available){
    digitalWrite(LED_PIN, HIGH);
    if(micro_ros_init_successful && !micro_ros_should_fini){
      rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100));
    } else {
      micro_ros_init_successful = init_micro_ros();
    }
  } else {
    digitalWrite(LED_PIN, LOW);
  }

  delayMicroseconds(500);
}

With this loop, the Led is always off. Plus, when the agent is launched, no entity is being initialized.
May be there is something that I missed. Is it possible to check the agent status, even if no entity has been created ?
About the RWM parameters, it would be nice for us to have a settable timeout to get the destroying confirmation (as we need to control our application rate).

Regarding the LED, have your client init session in the agent? rmw_uros_check_agent_status(10) == RMW_RET_OK this is only true if you have initialized session and the client is able to talk to the agent.
Yes, there is a way of checking if the agent is alive without creating a session. Give us a couple of days for implementing it.
Regarding the configurable timeout for creating and destroying entities, I think that it is completely necessary, so for sure, we are going to implement this ASAP.
I'm coming back in a while with these improvements.

have your client init session in the agent?

The session is created when doing :
  rclc_support_init(&support, 0, NULL, &allocator);
  node = rcl_get_zero_initialized_node();
  rclc_node_init_default(&node, "micro_ros_arduino_node", "", &support);

... is this right? If so, no, I don't create any session before checking on the agent status. Because I would rather not create entities if no agent is available to talk with. This is not a steady idea, it can be changed.The reason of this design is that we might differentiate these cases:

No agent is available (--> LED blinking, waiting for agent to become available, running "basic" functions)
An agent is available but the client is not cleanly initialized/not able to communicate with agent (--> LED off, try to initialize entities,  running "basic" functions)
Client / agent communication is correctly set up (--> LED on,  running "basic" and "Ros-related" functions)
The LED behavior is just for me to debug at first, but as you can see, different features of our application would be executed according to the case. So we would need to test the agent state every loop (50Hz in our case), no matter if there is an established session or not. I hope this is clear, if not let me know, I could provide an lightened code.
But as I said, it is not a settled design yet. Do you think there are problems that could occur because of such a design?

Thank you very much for support! I am looking forward to use the new features.

Ok, we are going to study this and we will come back with a solution.
My colleague @jamoralp is going to be also involved. Give us a couple of days.

Hi @pablogs9 , @jamoralp
Any news about implementing this (these?) feature(s) ? We are still super interesting into being able to detect whether there an available agent or not with a settable timeout. Thank you !

Hello @anaelle-sw, sorry for the delay, @jamoralp is working on it but we have some end-of-the-year documents and bureaucracy. But as soon as we complete this, he is going to release this ping feature.
Sorry again for the delay... hope that this is not blocking your development.

Thanks for your quick answer!
It is no problem at all, we can sure wait. We are able to pursue our development on ROS2, without any issue related to our Micro-ROS application.
Thanks a lot for your awesome support!

Good morning @anaelle-sw and happy new year.
I finally had some time to make interesting progress in the way of implementing a true ping functionality between the micro XRCE-DDS client and agent applications. You can check the current status of this functionality on the corresponding pull request for the client and agent. You might want to switch to those branches before testing this new functionality.
To illustrate how it works, I prepared some simple examples. These are meant to be run in host machines; however, running them on an embedded device should not differ too much. Actually, I was able to ping from an Olimex board, using the serial port, to an agent, successfully.
Currently there is no implementation regarding the micro-ROS rmw, but we are thinking of a way to make the rmw ping method more sophisticated, so you can specify the uxrCommunication* struct pointer to which redirect the ping petition, in case the micro-ROS context has not been initialized yet (as in your use case); or grab it from the context, in case it has been initialized. Anyway, I would like to discuss this with @pablogs9 once he comes back from Christmas holidays :slightly_smiling_face:
Feel free to ask about any doubts or suggest further improvements/fixes on this topic and I'll be happy to address them. Thanks!

Good morning @anaelle-sw and happy new year.
I finally had some time to make interesting progress in the way of implementing a true ping functionality between the micro XRCE-DDS client and agent applications. You can check the current status of this functionality on the corresponding pull request for the client and agent. You might want to switch to those branches before testing this new functionality.
To illustrate how it works, I prepared some simple examples. These are meant to be run in host machines; however, running them on an embedded device should not differ too much. Actually, I was able to ping from an Olimex board, using the serial port, to an agent, successfully.
Currently there is no implementation regarding the micro-ROS rmw, but we are thinking of a way to make the rmw ping method more sophisticated, so you can specify the uxrCommunication* struct pointer to which redirect the ping petition, in case the micro-ROS context has not been initialized yet (as in your use case); or grab it from the context, in case it has been initialized. Anyway, I would like to discuss this with @pablogs9 once he comes back from Christmas holidays :slightly_smiling_face:
Feel free to ask about any doubts or suggest further improvements/fixes on this topic and I'll be happy to address them. Thanks!

Hi @jamoralp , thank you, happy new year to you too!
Thanks for this new feature! I would be happy to try it, but I have some trouble to adapt your example code for our Teensy board, using micro_ros_arduino. I have installed micro XRCE-DDS from source from your PR branches, have re-build micro_ros_arduino, and have copied the ping.h file in the micro_ros_arduino library (Arduino/libraries/src/uxr/client/util). But I am still not able to build a .ino simple example, based on your .c example. I got the error: undefined reference to 'uxr_ping_agent_attempts'  when compiling. Do you know if I am supposed to directly use uxr_ping_agent_attempts function as you did in the example, but with micro_ros_arduino? Actually, I am a bit lost here, as I am not used to use the function open to open communication between the agent and client. Sorry if this is not clear or not relevant.

we are thinking of a way to make the rmw ping method more sophisticated...

This could be really nice for us. Maybe the problem I explained above will be more easily solved by implementing a rmw ping method (rather than adapting the uxr_ping_agent_attempts function for micro_ros_arduino).
Thanks a lot for helping!

Hi @jamoralp , thank you, happy new year to you too!
Thanks for this new feature! I would be happy to try it, but I have some trouble to adapt your example code for our Teensy board, using micro_ros_arduino. I have installed micro XRCE-DDS from source from your PR branches, have re-build micro_ros_arduino, and have copied the ping.h file in the micro_ros_arduino library (Arduino/libraries/src/uxr/client/util). But I am still not able to build a .ino simple example, based on your .c example. I got the error: undefined reference to 'uxr_ping_agent_attempts'  when compiling. Do you know if I am supposed to directly use uxr_ping_agent_attempts function as you did in the example, but with micro_ros_arduino? Actually, I am a bit lost here, as I am not used to use the function open to open communication between the agent and client. Sorry if this is not clear or not relevant.

we are thinking of a way to make the rmw ping method more sophisticated...

This could be really nice for us. Maybe the problem I explained above will be more easily solved by implementing a rmw ping method (rather than adapting the uxr_ping_agent_attempts function for micro_ros_arduino).
Thanks a lot for helping!

Hi @jamoralp , thank you, happy new year to you too!
Thanks for this new feature! I would be happy to try it, but I have some trouble to adapt your example code for our Teensy board, using micro_ros_arduino. I have installed micro XRCE-DDS from source from your PR branches, have re-build micro_ros_arduino, and have copied the ping.h file in the micro_ros_arduino library (Arduino/libraries/src/uxr/client/util). But I am still not able to build a .ino simple example, based on your .c example. I got the error: undefined reference to 'uxr_ping_agent_attempts'  when compiling. Do you know if I am supposed to directly use uxr_ping_agent_attempts function as you did in the example, but with micro_ros_arduino? Actually, I am a bit lost here, as I am not used to use the function open to open communication between the agent and client. Sorry if this is not clear or not relevant.

Morning! Regarding this first part, I certainly did not test this under an Arduino platform, so some changes might have to be introduced to the precompiled library; as it has not been merged yet, our automatic processes do not have triggered the build of the micro-ROS arduino library, so that might be the reason this is not working. Let met look into it a little bit. Regarding the open functionality: that is something specific of Linux operating systems, so we get and associated file descriptor to the serial port that can then be used to initialize the micro-XRCE DDS Serial transport (see https://github.com/eProsima/Micro-XRCE-DDS-Client/blob/66df0a6df20063d246dd638ac3d33eb2e652fab2/include/uxr/client/profile/transport/serial/serial_transport.h#L56). For you board, I believe you should just call the uxr_init_serial_transport method, as this method underneath calls the uxr_init_serial_platform method and it is taking care of opening the Arduino serial port accordingly (https://github.com/micro-ROS/micro_ros_arduino/blob/489dfec8eb3acda61b83d02e9c47202f99dda27e/extras/library_generation/arduino_xrce_transports/serial_transport_external.c#L6).

we are thinking of a way to make the rmw ping method more sophisticated...

This could be really nice for us. Maybe the problem I explained above will be more easily solved by implementing a rmw ping method (rather than adapting the uxr_ping_agent_attempts function for micro_ros_arduino).

Yes, this sounds completely reasonable to me. We need to find a way to make this more "micro-ROS" and less "micro XRCE-DDS"; however, when no ROS context has been created (using the rclc_support_init function), no transport is available in the context, so it has to be initialized and provided manually. We also had first thoughts about the ping function to open and close the transport, but that was not feasible on the xrce layer. Maybe the micro-ROS method could have this intelligent behaviour if no transport has been initialized yet. What do you think about this?

Thanks a lot for helping!

Hi @jamoralp , thank you, happy new year to you too!
Thanks for this new feature! I would be happy to try it, but I have some trouble to adapt your example code for our Teensy board, using micro_ros_arduino. I have installed micro XRCE-DDS from source from your PR branches, have re-build micro_ros_arduino, and have copied the ping.h file in the micro_ros_arduino library (Arduino/libraries/src/uxr/client/util). But I am still not able to build a .ino simple example, based on your .c example. I got the error: undefined reference to 'uxr_ping_agent_attempts'  when compiling. Do you know if I am supposed to directly use uxr_ping_agent_attempts function as you did in the example, but with micro_ros_arduino? Actually, I am a bit lost here, as I am not used to use the function open to open communication between the agent and client. Sorry if this is not clear or not relevant.

Morning! Regarding this first part, I certainly did not test this under an Arduino platform, so some changes might have to be introduced to the precompiled library; as it has not been merged yet, our automatic processes do not have triggered the build of the micro-ROS arduino library, so that might be the reason this is not working. Let met look into it a little bit. Regarding the open functionality: that is something specific of Linux operating systems, so we get and associated file descriptor to the serial port that can then be used to initialize the micro-XRCE DDS Serial transport (see https://github.com/eProsima/Micro-XRCE-DDS-Client/blob/66df0a6df20063d246dd638ac3d33eb2e652fab2/include/uxr/client/profile/transport/serial/serial_transport.h#L56). For you board, I believe you should just call the uxr_init_serial_transport method, as this method underneath calls the uxr_init_serial_platform method and it is taking care of opening the Arduino serial port accordingly (https://github.com/micro-ROS/micro_ros_arduino/blob/489dfec8eb3acda61b83d02e9c47202f99dda27e/extras/library_generation/arduino_xrce_transports/serial_transport_external.c#L6).

we are thinking of a way to make the rmw ping method more sophisticated...

This could be really nice for us. Maybe the problem I explained above will be more easily solved by implementing a rmw ping method (rather than adapting the uxr_ping_agent_attempts function for micro_ros_arduino).

Yes, this sounds completely reasonable to me. We need to find a way to make this more "micro-ROS" and less "micro XRCE-DDS"; however, when no ROS context has been created (using the rclc_support_init function), no transport is available in the context, so it has to be initialized and provided manually. We also had first thoughts about the ping function to open and close the transport, but that was not feasible on the xrce layer. Maybe the micro-ROS method could have this intelligent behaviour if no transport has been initialized yet. What do you think about this?

Thanks a lot for helping!

Good morning!
Thanks for your answer, it is clearer now. I will just wait for your PR to be merged and to be added to micro-ROS. I will let you know when I am able to test it.

We also had first thoughts about the ping function to open and close the transport, but that was not feasible on the xrce layer. Maybe the micro-ROS method could have this intelligent behaviour if no transport has been initialized yet. What do you think about this?

I agree with you about this from an user point of view (but I really don't know about the feasibility).
For now, we are not stuck in our development by our micro-ROS/Teensy application, but quick re-connection to ROS is quite an important feature. Do you know about when this feature would be available? Do you want me to temporary close this issue and open a new one when needed?
Thanks a lot!

Good morning!
Thanks for your answer, it is clearer now. I will just wait for your PR to be merged and to be added to micro-ROS. I will let you know when I am able to test it.

We also had first thoughts about the ping function to open and close the transport, but that was not feasible on the xrce layer. Maybe the micro-ROS method could have this intelligent behaviour if no transport has been initialized yet. What do you think about this?

I agree with you about this from an user point of view (but I really don't know about the feasibility).
For now, we are not stuck in our development by our micro-ROS/Teensy application, but quick re-connection to ROS is quite an important feature. Do you know about when this feature would be available? Do you want me to temporary close this issue and open a new one when needed?
Thanks a lot!

Good afternoon, and good news! The ping feature has now been fully implemented for micro-ROS. You can find a demo application I prepared for this purpose here: https://github.com/micro-ROS/micro-ROS-demos/blob/foxy/rclc/ping_uros_agent/main.c
This demo application waits until there is an agent available, then starts creating micro-ROS entities. During the callback of the implemented timer, if the agent goes down, the application itself exits automatically.
I hope that, with this example and new functionality, you find it easy to fulfill your requirements. Please report if this works for you, and then close this issue if, hopefully, no problems arise; if that is the case, we will be happy to help, as usual :slightly_smiling_face:
Have a nice day!

I'm working on regenerating the libraries in the official Arduino repo, currently, they are outdated.

The libraries are updated. Check https://github.com/micro-ROS/micro_ros_arduino/pull/113.

Good morning @anaelle-sw did you have time to check this up? It would be really great for us to have some feedback about a real use-case using this new feature :slightly_smiling_face:

Hi @jamoralp! I am working on it, but as we are in the middle of transition to Rolling, I was not able to test the implementation in our use-case for now.  All I can say for now, is that the re-connection example works great!
I will let you know next Monday/Tuesday how it works for our complete application. Thanks!

Ok, no problem! Just wanted to make sure that you noticed about the release status, since I did not mention you in my previous comment. Have a nice weekend!

Good morning!
I tried to implement the feature to ping the agent but it doesn't work the way I expected it to.
So I tried to modify step by step the re-connection example to get close to the implementation in our complete application. I found out that trying to ping the agent without having any ROS node/support/executor makes the code being stuck. For instance, in the re-connection example, I modified the setup function so that it initializes ROS entities, if the agent is detected:
void setup() {
  set_microros_transports();
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);

  micro_ros_init_successful = false;
  msg.data = 0;

  rmw_ret_t rc = rmw_uros_ping_agent(10, 1);
  if ( rc == RMW_RET_OK) {
    micro_ros_init_successful = init_micro_ros();
  }
}

With this, nothing happens, the board is stuck, and the agent output is:
[1613381744.637500] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 3
[1613381745.137887] info     | TermiosAgentLinux.cpp | fini                     | server stopped         | fd: 3
[1613381745.138269] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 3

I guess I am not supposed to use this function without having any client/agent session initialized.
If I get it right, the design in the example code consists in trying to initialized the ROS entities. If an error is return trying this, it tries again at next loop, until it works. Then, it pings the agent in a timer callback, and if no agent is found, the ROS entities are destroyed.
I am not really a big fan of this design for two reasons.
First, I don't think it is really nice in terms of logic/design to try to initialize ROS entities, while knowing that it may not work if no agent is available. Actually, in our use case, the agent may not be available quite regularly.
Secondly, the main reason is that initializing a ROS entity could failed because of something else that the agent not being available (is this right?). I would like to be able to distinguish both cases: is my application not working because of
1- the agent not responding when being ping?
2- the entities not being correctly initialized?
Well in brief, would it be possible to have a ping function that would work without having initialized any ROS node/executor/support initialized?

Sorry if my example led to confussion, I was just trying to illustrate how the ping method works but by any means this should imply that it could be actually useful for your use case.
However, I am not really understading what is happening to your Agent. Could you run it using the -v6 option? It seems that the server is endlessly being initialized and finished and that is definitely not an expected behaviour, unless it is intended.
Regarding the implementation of the ping method in the rmw, have a look at this: https://github.com/micro-ROS/rmw-microxrcedds/blob/foxy/rmw_microxrcedds_c/src/rmw_uros_options.c#L222 and this https://github.com/micro-ROS/rmw-microxrcedds/blob/foxy/rmw_microxrcedds_c/src/rmw_uxrce_transports.c
What we did was guessing if an rmw_context has already been initialized or not. If that is not the case, you would go over to rmw_uros_options.c:222 and init a XRCE transport entity, then attempt to ping, then close the transport. The transport will be initialized with DEFAULT options. This means, in the case of a serial device, https://github.com/micro-ROS/rmw-microxrcedds/blob/7ff87b345012ea169879cce7deb91704adcaf059/rmw_microxrcedds_c/CMakeLists.txt#L81. Could this be causing some trouble in your application?

Ok, thanks for your answer. Nice to know that the ping feature should work great too for our application.
The agent output I copied is obtained when launching it with the -v6 option.
The thing is that the micro-ros Arduino re-connection example works really nicely. But if I try to ping the agent in the setup function, nothing works anymore.

https://github.com/micro-ROS/rmw-microxrcedds/blob/7ff87b345012ea169879cce7deb91704adcaf059/rmw_microxrcedds_c/CMakeLists.txt#L81

Maybe this is the problem, you're right, since our board has a dev renamed. But it is strange that the agent ping is working when node/executor/support are initialized, but is not otherwise.

Ok, I have found some serious issues when using the function we provide with custom transport, and without a ROS 2 context (e.g. node) initialized. I've uploaded a fix but @pablogs9 is going to test it, since I'm busy with other tasks. Have a look at https://github.com/micro-ROS/rmw-microxrcedds/pull/105

Thanks a lot for your help and the quick fix!

Hello @anaelle-sw,

I have merged the fix: https://github.com/micro-ROS/rmw-microxrcedds/pull/105
I have updated the reconnection example to something closer to your use case

main: https://github.com/micro-ROS/micro_ros_arduino/pull/128
foxy: https://github.com/micro-ROS/micro_ros_arduino/pull/127

In this new example the loop will be running despite micro-ROS is running or not, in the case micro-ROS is up the LED will flash slowly and if it is down the LED will flash fast. You can open and close the agent to check the behavior.
Remember that functions create_entities and destroy_entities can take up to several seconds depending on the configuration. So I have set:

UCLIENT_MAX_SESSION_CONNECTION_ATTEMPTS=3 means that it will try to create or destroy a session 3
RMW_UXRCE_ENTITY_CREATION_DESTROY_TIMEOUT=0 means that the ROS 2 entities creation and destruction will be handled by XRCE in best effort, so it won't be blocking.

My whole meta is:
{
    "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=OFF",
                "-UCLIENT_PROFILE_STREAM_FRAMING=ON",
                "-DUCLIENT_PROFILE_CUSTOM_TRANSPORT=ON",
                "-DUCLIENT_MAX_SESSION_CONNECTION_ATTEMPTS=3"
            ]
        },
        "rmw_microxrcedds": {
            "cmake-args": [
                "-DRMW_UXRCE_ENTITY_CREATION_DESTROY_TIMEOUT=0",
                "-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=1",
                "-DRMW_UXRCE_TRANSPORT=custom"
            ]
        }
    }
}

Hi!
The example code works great, thanks!
But I have to launch the agent being installed from sources. If I use the snap release (micro-ros-agent serial --dev /dev/teensy_elodie -v6), nothing happens, the output is:
[1613479528.347664] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 3
[1613479528.347885] info     | Root.cpp           | set_verbose_level        | logger setup           | verbose_level: 6

Sometimes, the output is the same but the agent crashes with error Segmentation fault (core dumped).
I check out if there are snap updates, but there is none. Should I open an issue about it in the micro-ros-agent repo?
I will try to use the features with our application and let you know how it turns out.

I'm using the docker version with:
docker run -it --rm --net=host -v /dev:/dev --privileged microros/micro-ros-agent:foxy serial --dev /dev/serial/by-id/usb-Teensyduino_USB_Serial_8180040-if00 -v6

I'm not sure about the update status of the snap version, @jamoralp any idea?
But for sure we should replicate and fix this Segmentation fault (core dumped)... Do you have some steps to reproduce this error @anaelle-sw?

Oh, sorry. Certainly the micro-ROS Agent snap builds are not automated, as it happens with the micro-XRCE DDS Agent snap. This is because of some experimental features that the guys from Snapcraft need to merge into their main stream before letting us complete the automatic build process. Therefore, I will upload a new version of the micro-ROS Agent ASAP.

Nice, thanks!
Maybe we can close this when @jamoralp uploads the new snap version.

Well, actually I got a new problem.
I upload the reconnection example on a Teensy board, and launch the micro-ros agent (from sources or from docker, the result is the same either way). After sending some messages, the error terminate called after throwing an instance of 'std::bad_alloc' occurs. This is the complete output:
[1613484371.340945] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 3
[1613484371.341067] info     | Root.cpp           | set_verbose_level        | logger setup           | verbose_level: 6
[1613484371.420326] info     | Root.cpp           | create_client            | create                 | client_key: 0x5FBF8BF2, session_id: 0x81
[1613484371.420443] info     | SessionManager.hpp | establish_session        | session established    | client_key: 0x1606388722, address: 0
[1613484371.420529] info     | SessionManager.hpp | establish_session        | session re-established | client_key: 0x1606388722, address: 0
[1613484371.420634] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x5FBF8BF2, len: 19, data:
0000: 81 00 00 00 04 01 0B 00 00 00 58 52 43 45 01 00 01 0F 00
[1613484371.420696] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x5FBF8BF2, len: 19, data:
0000: 81 00 00 00 04 01 0B 00 00 00 58 52 43 45 01 00 01 0F 00
[1613484371.425981] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x5FBF8BF2, len: 12, data:
0000: 81 00 00 00 03 01 04 00 00 02 FF FE
[1613484371.426045] info     | Root.cpp           | delete_client            | delete                 | client_key: 0x5FBF8BF2
[1613484371.426062] info     | SessionManager.hpp | destroy_session          | session closed         | client_key: 0x5FBF8BF2, address: 0
[1613484372.219194] info     | Root.cpp           | create_client            | create                 | client_key: 0x55CDC000, session_id: 0x81
[1613484372.219268] info     | SessionManager.hpp | establish_session        | session established    | client_key: 0x1439547392, address: 0
[1613484372.219370] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 19, data:
0000: 81 00 00 00 04 01 0B 00 00 00 58 52 43 45 01 00 01 0F 00
[1613484372.225085] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x55CDC000, len: 24, data:
0000: 80 00 00 00 00 01 10 00 58 52 43 45 01 00 01 0F 55 CD C0 00 81 00 FC 01
[1613484372.225245] info     | SessionManager.hpp | establish_session        | session re-established | client_key: 0x1439547392, address: 0
[1613484372.225365] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 19, data:
0000: 81 00 00 00 04 01 0B 00 00 00 58 52 43 45 01 00 01 0F 00
[1613484372.230341] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x55CDC000, len: 24, data:
0000: 80 00 00 00 00 01 10 00 58 52 43 45 01 00 01 0F 55 CD C0 00 81 00 FC 01
[1613484372.230440] info     | SessionManager.hpp | establish_session        | session re-established | client_key: 0x1439547392, address: 0
[1613484372.230549] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 19, data:
0000: 81 00 00 00 04 01 0B 00 00 00 58 52 43 45 01 00 01 0F 00
[1613484372.230609] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x55CDC000, len: 108, data:
0000: 81 80 00 00 01 05 64 00 00 0A 00 01 01 02 00 00 55 00 00 00 3C 64 64 73 3E 3C 70 61 72 74 69 63
0020: 69 70 61 6E 74 3E 3C 72 74 70 73 3E 3C 6E 61 6D 65 3E 69 6E 74 33 32 5F 70 75 62 6C 69 73 68 65
0040: 72 5F 72 63 6C 63 3C 2F 6E 61 6D 65 3E 3C 2F 72 74 70 73 3E 3C 2F 70 61 72 74 69 63 69 70 61 6E
0060: 74 3E 3C 2F 64 64 73 3E 00 00 00 00
[1613484372.230805] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x55CDC000, len: 132, data:
0000: 81 80 01 00 01 05 7B 00 00 0B 00 02 02 02 00 00 6D 00 00 00 3C 64 64 73 3E 3C 74 6F 70 69 63 3E
0020: 3C 6E 61 6D 65 3E 72 74 2F 73 74 64 5F 6D 73 67 73 5F 6D 73 67 5F 49 6E 74 33 32 3C 2F 6E 61 6D
0040: 65 3E 3C 64 61 74 61 54 79 70 65 3E 73 74 64 5F 6D 73 67 73 3A 3A 6D 73 67 3A 3A 64 64 73 5F 3A
0060: 3A 49 6E 74 33 32 5F 3C 2F 64 61 74 61 54 79 70 65 3E 3C 2F 74 6F 70 69 63 3E 3C 2F 64 64 73 3E
0080: 00 00 01 00
[1613484372.230823] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x55CDC000, len: 24, data:
0000: 81 80 02 00 01 05 0F 00 00 0C 00 03 03 02 00 00 01 00 00 00 00 00 01 00
[1613484372.232419] debug    | ProxyClient.cpp    | create_participant       | participant created    | client_key: 0x55CDC000, participant_id: 0x000(1)
[1613484372.232470] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 14, data:
0000: 81 80 00 00 05 01 06 00 00 0A 00 01 00 00
[1613484372.232482] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1613484372.232536] debug    | ProxyClient.cpp    | create_topic             | topic created          | client_key: 0x55CDC000, topic_id: 0x000(2), participant_id: 0x000(1)
[1613484372.232562] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 14, data:
0000: 81 80 01 00 05 01 06 00 00 0B 00 02 00 00
[1613484372.232572] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0A 01 05 00 02 00 00 00 80
[1613484372.232601] debug    | ProxyClient.cpp    | create_publisher         | publisher created      | client_key: 0x55CDC000, publisher_id: 0x000(3), participant_id: 0x000(1)
[1613484372.232623] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 14, data:
0000: 81 80 02 00 05 01 06 00 00 0C 00 03 00 00
[1613484372.232631] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0A 01 05 00 03 00 00 00 80
[1613484372.234997] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x55CDC000, len: 356, data:
0000: 81 80 03 00 01 05 59 01 00 0D 00 05 05 02 00 00 4B 01 00 00 3C 64 64 73 3E 3C 64 61 74 61 5F 77
0020: 72 69 74 65 72 3E 3C 68 69 73 74 6F 72 79 4D 65 6D 6F 72 79 50 6F 6C 69 63 79 3E 50 52 45 41 4C
0040: 4C 4F 43 41 54 45 44 5F 57 49 54 48 5F 52 45 41 4C 4C 4F 43 3C 2F 68 69 73 74 6F 72 79 4D 65 6D
0060: 6F 72 79 50 6F 6C 69 63 79 3E 3C 71 6F 73 3E 3C 72 65 6C 69 61 62 69 6C 69 74 79 3E 3C 6B 69 6E
0080: 64 3E 42 45 53 54 5F 45 46 46 4F 52 54 3C 2F 6B 69 6E 64 3E 3C 2F 72 65 6C 69 61 62 69 6C 69 74
00A0: 79 3E 3C 2F 71 6F 73 3E 3C 74 6F 70 69 63 3E 3C 6B 69 6E 64 3E 4E 4F 5F 4B 45 59 3C 2F 6B 69 6E
00C0: 64 3E 3C 6E 61 6D 65 3E 72 74 2F 73 74 64 5F 6D 73 67 73 5F 6D 73 67 5F 49 6E 74 33 32 3C 2F 6E
00E0: 61 6D 65 3E 3C 64 61 74 61 54 79 70 65 3E 73 74 64 5F 6D 73 67 73 3A 3A 6D 73 67 3A 3A 64 64 73
0100: 5F 3A 3A 49 6E 74 33 32 5F 3C 2F 64 61 74 61 54 79 70 65 3E 3C 68 69 73 74 6F 72 79 51 6F 73 3E
0120: 3C 6B 69 6E 64 3E 4B 45 45 50 5F 41 4C 4C 3C 2F 6B 69 6E 64 3E 3C 2F 68 69 73 74 6F 72 79 51 6F
0140: 73 3E 3C 2F 74 6F 70 69 63 3E 3C 2F 64 61 74 61 5F 77 72 69 74 65 72 3E 3C 2F 64 64 73 3E 00 00
0160: 03 00 00 00
[1613484372.235545] debug    | ProxyClient.cpp    | create_datawriter        | datawriter created     | client_key: 0x55CDC000, datawriter_id: 0x000(5), publisher_id: 0x000(3)
[1613484372.235576] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 14, data:
0000: 81 80 03 00 05 01 06 00 00 0D 00 05 00 00
[1613484372.235583] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0A 01 05 00 04 00 00 00 80
[1613484372.541866] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0B 01 05 00 00 00 03 00 80
[1613484372.742018] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0B 01 05 00 00 00 03 00 80
[1613484372.878172] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x55CDC000, len: 16, data:
0000: 80 00 00 00 02 01 08 00 00 09 FF FD 02 00 00 00
[1613484372.878482] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 36, data:
0000: 80 00 00 00 06 01 1C 00 00 09 FF FD 00 00 01 0D 58 52 43 45 01 00 01 0F 00 01 0D 00 01 00 00 00
0020: 00 00 00 00
[1613484372.896140] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0B 01 05 00 00 00 03 00 80
[1613484372.896177] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0B 01 05 00 00 00 03 00 80
[1613484372.896265] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0A 01 05 00 04 00 00 00 80
[1613484372.896283] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0A 01 05 00 04 00 00 00 80
[1613484372.897291] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0B 01 05 00 00 00 03 00 80
[1613484372.897381] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0A 01 05 00 04 00 00 00 80
[1613484372.942034] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0B 01 05 00 00 00 03 00 80
[1613484373.142398] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0B 01 05 00 00 00 03 00 80
[1613484373.342495] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0B 01 05 00 00 00 03 00 80
[1613484373.403950] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x55CDC000, len: 16, data:
0000: 80 00 00 00 02 01 08 00 00 09 FF FD 02 00 00 00
[1613484373.404075] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 36, data:
0000: 80 00 00 00 06 01 1C 00 00 09 FF FD 00 00 01 0D 58 52 43 45 01 00 01 0F 00 01 0D 00 01 00 00 00
0020: 00 00 00 00
[1613484373.430069] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x55CDC000, len: 16, data:
0000: 81 01 00 00 07 01 08 00 00 0E 00 05 00 00 00 00
[1613484373.430186] debug    | DataWriter.cpp     | write                    | [** <<DDS>> **]        | client_key: 0x00000000, len: 4, data:
0000: 00 00 00 00
[1613484373.542614] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0B 01 05 00 00 00 03 00 80
[1613484373.742755] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0B 01 05 00 00 00 03 00 80
[1613484373.931080] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x55CDC000, len: 16, data:
0000: 80 00 00 00 02 01 08 00 00 09 FF FD 02 00 00 00
[1613484373.931423] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 36, data:
0000: 80 00 00 00 06 01 1C 00 00 09 FF FD 00 00 01 0D 58 52 43 45 01 00 01 0F 00 01 0D 00 01 00 00 00
0020: 00 00 00 00
[1613484373.942995] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0B 01 05 00 00 00 03 00 80
[1613484373.944154] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0B 01 05 00 00 00 03 00 80

[ . . . ]

[1613484375.531102] debug    | DataWriter.cpp     | write                    | [** <<DDS>> **]        | client_key: 0x00000000, len: 4, data:
0000: 02 00 00 00
[1613484375.544150] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0B 01 05 00 00 00 03 00 80
[1613484375.744214] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0B 01 05 00 00 00 03 00 80
[1613484375.944586] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0B 01 05 00 00 00 03 00 80
[1613484376.032183] debug    | SerialAgentLinux.cpp | recv_message             | [==>> SER <<==]        | client_key: 0x55CDC000, len: 16, data:
0000: 80 00 00 00 02 01 08 00 00 09 FF FD 02 00 00 00
[1613484376.032476] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 36, data:
0000: 80 00 00 00 06 01 1C 00 00 09 FF FD 00 00 01 0D 58 52 43 45 01 00 01 0F 00 01 0D 00 01 00 00 00
0020: 00 00 00 00
[1613484376.144775] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0B 01 05 00 00 00 03 00 80
[1613484376.344992] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x55CDC000, len: 13, data:
0000: 81 00 00 00 0B 01 05 00 00 00 03 00 80
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

When running another example (the publisher one for instance), everything works well.
As it only happens on one of the two computers I am using to test the reconnection feature, I am trying to figure out what can cause this. I will let you know if I find something.

Hmm, that sounds weird. Let us know if you find something more about this issue, or share the specific steps to reproduce it, please

Well I tried to completely remove micro-ros-arduino library and build it from scratch, as I thought it may be due to a problem during installation, but the same error occurs. Here are the steps to reproduce:
# clone the repo
cd ~/Arduino/libraries
sudo rm -r micro_ros_arduino
git clone -b main https://github.com/micro-ROS/micro_ros_arduino.git

# add the custom meta file (the one pablogs9 gave above)
cd ~
cat ~/colcon_lowmem.meta > ~/Arduino/libraries/micro_ros_arduino/extras/library_generation/colcon_lowmem.meta

# add custom messages
cd ~/Arduino/libraries/micro_ros_arduino/extras/library_generation/extra_packages
cp -r ~/path/to/custom/msgs ~/Arduino/libraries/micro_ros_arduino/extras/library_generation/extra_packages

# update and build micro_ros_arduino
cd ~/Arduino/libraries/micro_ros_arduino
sudo docker pull microros/micro_ros_arduino_builder:rolling
sudo docker run -it --rm -v $(pwd):/arduino_project microros/micro_ros_arduino_builder:rolling -p teensy32

Then I upload the reconnection example on the Teensy board, and I run the agent:
sudo docker run -it --rm --net=host -v /dev:/dev --privileged microros/micro-ros-agent:rolling serial --dev /dev/teensy_elodie -v6

And this returns the output I gave above, with the error terminate called after throwing an instance of 'std::bad_alloc'

I have been able to reproduce it once and now it is possible to see it again. In the same computer.

Ok, thanks for helping on this.
Now I can even make the agent crash with the simple publisher example running, always on the same computer. I still have no clue on what is making the agent crash, but working on it

It might be an "internal problem" of the agent, since this is running on my board:
#define LED_PIN 13

void setup() {
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);
}

void loop() {
  digitalWrite(LED_PIN, !digitalRead(LED_PIN));
  delayMicroseconds(100000);
}

And when I run the agent (docker version: sudo docker run -it --rm --net=host -v /dev:/dev --privileged microros/micro-ros-agent:rolling serial --dev /dev/teensy_elodie -v6), I got this:
[1613490594.633615] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 4
[1613490594.633741] info     | Root.cpp           | set_verbose_level        | logger setup           | verbose_level: 6

And roughly 10sec after launch, the agent crashes:
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

If I have understood well, in this last case @anaelle-sw your Teensy application does not have micro-ROS on it, isn't it?
In that case, the agent is just connected to a serial port that is nos using micro-ROS, so I guess that the problem does not appear because of a micro-ROS feature like publishing or the new ping, it should be:

Something related to handling serial ports in Agent
Something related to FastDDS

Any idea @jamoralp ?

If I have understood well, in this last case @anaelle-sw your Teensy application does not have micro-ROS on it, isn't it?

Exactly, the Teensy is connected to the computer, but there is no micro-ROS running on it, the library is not even included. The agent seems to detect the serial connection, as it is not crashing because of not finding the device.
What is annoying is that I am not able to reproduce this on my second computer, even if I followed the exact same steps to install micro-ROS, load the code to the Teensy, run the agent, etc...

I will say that it can be an isolated issue of your setup in this specific computer... but yesterday I saw this same error once in my machine, I have not been able to reproduce it again.

Ok. I am interested in any idea you can have on what I should check about this computer's setup.

Does this computer have an updated version of ROS 2?
Have you installed multiple versions of ROS 2?
Is there a possibility of you having multiple FastDDS libraries installed?
@jamoralp:
Are we sure that de docker agent has SHM disabled?

ROS2 version is Rolling, up to date on both computers I am using for tests (last update was two days ago)
I used to have ROS2 Foxy on both computer, but it was removed before installing Rolling (I checked this, there is no Foxy package remaining)
We are currently using CycloneDDS, as it is the default rmw implementation for Rolling. But I do have FastDDS installed from binaries (ros-rolling-fastrtps) on both computers. But I am not yet super comfortable with RMW and dockers, may be you can help me:

How can I check the RMW implementation the agent running with docker is using?
Is the agent suppose to run only with FastDDS?
Can I force it to use this implementation when running the agent with docker?

Thanks a lot

Good afternoon @anaelle-sw, I am going to try to answer to every question as thoroughly as possible.

The Agent will always use FastDDS as the default middleware for translating XRCE entities into the DDS world. That being said, if you are running the foxy agent, FastDDS will already come as a precompiled dynamic library and the micro-ROS Agent will link against it. For the rolling docker, as galactic will use CycloneDDS, it is possible that the library is not precompiled, so the micro-ROS Agent will use the dynamic library that we compile from sources during the Micro-XRCE-DDS-Agent dynamic library generation.

Also related with this, we have detected some serious issues that could be cause an ABI breakage when the required FastDDS library version required by the Micro XRCE-DDS Agent dynamic library and the one already present in the foxy docker do not match. Basically, the Micro XRCE-DDS Agent is using its own compiled-from-source version of the library, whereas the micro-ROS Agent is finding Fast-DDS from the /opt/ros/foxy/lib directory. We are already working in fixing this.

Currently there is no known limitation for using FastDDS from the agent side to go into the ROS world, then having another ROS2 application in the same (or another) docker container using galactic and hence CycloneDDS RMW implementation. The two implementations should use the same serialization mechanism and be interoperable. If some issues arise, the guys from the FastDDS team might provide some help.
You can always force running ROS2 using our RMW implementation in the galactic docker. Simply run the following command:$ export RMW_IMPLEMENTATION=rmw_fastrtps_cpp.

Good morning @jamoralp, thanks for these detailed answers!
I am still trying to understand why this specific computer is making the Rolling docker that runs the agent crash. I tried to force either CycloneDDS or FastDDS, but it still crashes really often with the same allocation error.
The Foxy docker runs without any issue though. So, based on what you said about RWM implementations' interoperability, I tried to run an agent with a Foxy docker, and get messages with local computer on Rolling. It seems a little risky to me to mix ROS versions this way, but for the moment it works well and allows us to pursue the development with Rolling.

Good morning @anaelle-sw, you're welcome.
The last thing you said about it happening just on the ros:rolling docker gave us a hint on what the problem could be. We will keep you updated!

Hello @anaelle-sw, CC @jamoralp:
I have prepared a test agent for this case. It is custom baked with:

The same microros:rolling and ros:rolling base dockers
I have built it using static FastDDS linkage for the Micro-XRCE-DDS Agent
The micro-ROS Agent part related to FastDDS (basically the graph manager) is linked against the Rolling version of FastDDS.

To use it:
➜  docker run -it --rm --net=host -v /dev:/dev --privileged pablogs9/test_agent_wyca:latest
root@pgarrido:/uros_ws# source /opt/ros/rolling/setup.bash
root@pgarrido:/uros_ws# source install/local_setup.bash
root@pgarrido:/uros_ws# ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/teensy_elodie -v6

If our guesses are ok, with this there should not be interference between FastDDS versions...
Let me know if this solves the issue of bad alloc, if it still exists I have another idea, so let me know and I will create a new docker image for testing.

Thanks for helping!
Unfortunately, the agent still crashes with the same bad alloc error with this method. Always with a simple LED blink code running on the board, I tried to launch the agent 10 times, it crashed 6 times within the 5 first seconds after launch.

Ok, let me do some more testing.

The point is that the ros:rolling image comes with FastDDS 2.0.0 and the ros:foxy with FastDDS 2.0.2. Our colleagues in FastDDS have told us that at some point ros:rolling will use FastDDS 2.1.
So, is possible for you to use the foxy version of the Agent docker meanwhile?

Ok, I guess there is no problem to do this temporarily. My main concern doing this is about having a Foxy agent communicating with a ROS2 Rolling. But I did some tests this morning, it seems to work for now.

Yes, it should work for these cases because of DDS interoperability. I'm going to keep this open until we found a solution for the rolling micro-ROS agent.

Good morning @pablogs9 , @jamoralp
I saw there were some updates on the Rolling docker for the building micro-ROS-arduino library. So I tried to rebuild it and run the micro-ROS-agent on Rolling docker:
cd ~/Arduino/libraries/micro_ros_arduino
sudo docker pull microros/micro_ros_arduino_builder:rolling
sudo docker run -it --rm -v $(pwd):/arduino_project microros/micro_ros_arduino_builder:rolling -p teensy32
cd ~
sudo docker run -it --rm --net=host -v /dev:/dev --privileged microros/micro-ros-agent:rolling serial --dev /dev/teensy_elodie -v6

First, some good news: the micro-ROS agent doesn't automatically crash after few seconds after launch, as it used to on this same computer.
But it does crash sometimes, after our complete ROS2 application is launched. At first I thought it was because of my .ino code. So I uploaded this simple LED-blink code on the Teensy board (to be sure there would not be error caused by communication between Teensy - Agent - ROS2):
#include <micro_ros_arduino.h>
#define LED_PIN 13
void setup() {
  set_microros_transports();
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);
}
void loop() {
  digitalWrite(LED_PIN, !digitalRead(LED_PIN));
  delayMicroseconds(50000);
}

With this running on the Teensy, the agent was still automatically crashing after I launched our complete ROS2 application. After some tests, it seems that the agent is not crashing because of the nature of the nodes in our ROS2 application, but because of the quantity of ROS2 nodes running, since:
1 - When running our nodes almost one by one, with the agent running: the agent is not crashing
2 - I tried to launch this launch file, which launches a certain number of nodes from rclcpp_examples package:
from launch import *
from launch.actions import *
from launch.substitutions import *
from launch_ros.actions import *
from launch.launch_description_sources import *

def generate_launch_description():

    return LaunchDescription([

        Node(
            package = 'examples_rclcpp_minimal_subscriber',
            executable = 'subscriber_not_composable',
            name = 'node1',
            output = 'screen'
        ),
        Node(
            package = 'examples_rclcpp_minimal_subscriber',
            executable = 'subscriber_not_composable',
            name = 'node2',
            output = 'screen'
        ),
        Node(
            package = 'examples_rclcpp_minimal_subscriber',
            executable = 'subscriber_not_composable',
            name = 'node3',
            output = 'screen'
        ),
        Node(
            package = 'examples_rclcpp_minimal_subscriber',
            executable = 'subscriber_not_composable',
            name = 'node4',
            output = 'screen'
        ),
        Node(
            package = 'examples_rclcpp_minimal_subscriber',
            executable = 'subscriber_not_composable',
            name = 'node5',
            output = 'screen'
        ),
        Node(
            package = 'examples_rclcpp_minimal_subscriber',
            executable = 'subscriber_not_composable',
            name = 'node6',
            output = 'screen'
        ),
        Node(
            package = 'examples_rclcpp_minimal_subscriber',
            executable = 'subscriber_not_composable',
            name = 'node7',
            output = 'screen'
        ),
        Node(
            package = 'examples_rclcpp_minimal_subscriber',
            executable = 'subscriber_not_composable',
            name = 'node8',
            output = 'screen'
        ),
       # etc...
    ])

After a certain number of nodes being launched (around ~15-20, I did not succeed in identifying a precise limit), the agent crashes.
I hope this can help. Thank you for support!

Super cool, I got it!

Now I'm going to debug...

Hello @anaelle-sw, I have been testing with local build versions of Rolling Release and the Agent, moving between versions of Fast-DDS, but we have not found any consistent solution.
My colleague @EduPonz told me that despite ROS 2 repos should be using v2.1.x, the precompiled distribution packets (and the dockers) are using v2.0.0
Maybe he can notify us here when this version is bumped in the Rolling distribution, so we can upgrade the Dockers and check if this Agent error is solved.

I found that after running the agent, if I run a few more launch files, errors will be reported. About 6, 7 launches
[micro_ros_agent-1] terminate called after throwing an instance of 'std::bad_alloc'
[micro_ros_agent-1] what(): std::bad_alloc
app.c has an executor, 5 pubs and 2 subs. RCCHECK(rclc_executor_init(&executor, &support.context, 7, &allocator));
On another pc, an error occurs when running the 6 or 7 launch file
Is there a limit on the number of nodes or executors?

Hello, @anaelle-sw  and @ncnynl we have merged a solution for the library conflict here. I have been testing it under a ROS 2 environment and it seems to work.
Now we should not see the bad_alloc error anymore, hopefully... Could you test it and give some feedback? Just pull the newer docker or rebuild the agent using a fresh version of micro_ros_setup:
docker pull microros/micro-ros-agent:foxy
docker pull microros/micro-ros-rolling

Keep us updated, I'm closing but if you see the same error once again, please reopen.
Here you can see the new image builds: https://hub.docker.com/repository/docker/microros/micro-ros-agent/builds
CC: @Acuadros95

Hi @pablogs9
I tried to use the Rolling docker.
Everything works well until I launch all our complete ROS2 application. It seems that if there are a certain number of nodes launched, the agent just crash and throws:
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

It happens with the RMW implementation forced to CycloneDDS or to FastDDS.
I will build micro-ROS Arduino for Foxy and try also with the Foxy docker. I will let you know if this happens too.

Everything works well until I launch all our complete ROS2 application. It seems that if there are a certain number of nodes launched, the agent just crash and throws:
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

I cannot reproduce this with the Foxy docker

Ok, I have just pushed a new Rolling image 16 minutes ago: https://hub.docker.com/layers/microros/micro-ros-agent/rolling/images/sha256-dfc13408b694aed25a0ab997b628dc65a1a1c3b8f3948cbdc6f01f2de3a2dccd?context=repo
Please, let me know if you are able to reproduce the bad_alloc with this new docker image.
Remember to do docker pull microros/micro-ros-agent:rolling

It is nice, the Rolling docker doesn't crash anymore!
I guess this issue can be closed for now


Remove this use of "getParcelableExtra"

Describe the technical debt
A clear and concise description of what the technical debt is.
Proposed solution
If applicable:

add logcat output

Technical information

Device: [e.g. Nexus 7 (2013)]
OS: [e.g. LineageOS 15.1]
OpenTracks version: [e.g. v3.2.4]
OpenTracks commit id (only for nightly builds): [e.g. 4b333bb]

Issue resolved
Proposed solution:
Replaced 'getParcelableExtra' with 'getExtras().getParcelable()'
Replaced 'getParcelableArrayListExtra' with 'getExtras().getParcelableArrayList()'


Corrected tns-core-modules dependency version

As 2.1.0 version of tns-core-modules does not exist currently, I am not able to create new project using this template. So corrected it.

Can we get this merged? Sounds like it will help some folks! 👍
@enchev @vakrilov

@shripalsoni04, thank you for this pull request.
We are going to publish<EMAIL_ADDRESS>later this week as well as a new version of this template -<EMAIL_ADDRESS>Please use the tns create <App Name> --ng  command which takes the latest version of this template published in npm
//CC: @NathanWalker


udpate contributing

now out of date following #282
must have git installed I think
and install dev/doc is now
pip install .[dev]

I'll take a look at updating the contributing guidelines!


Add test requirements

Checklist

[x] Used a fork of the feedstock to propose changes
[ ] Bumped the build number (if the version is unchanged)
[ ] Re-rendered with the latest conda-smithy (Use the phrase @conda-forge-admin, please rerender in a comment in this PR for automated rerendering)

This tries to fix the CI testing on Linux.

Hi! This is the friendly automated conda-forge-linting service.
I just wanted to let you know that I linted all conda-recipes in your PR (recipe) and found it was in an excellent condition.

@conda-forge-admin, please rerender


Enable SD Card

Enable SD Card. Since my pull request was merged upstream (see https://github.com/micropython/micropython/pull/5185#event-2701488861), I suggest to enable the SD card. I tried, it works:
MicroPython v1.11-423-g06ae818f9 on 2019-10-10; MCUDEV STM32F407VE with STM32F407VE
Type "help()" for more information.
>>> import os
>>> os.listdir()
['System Volume Information', 'a.z80', 'virsynth.z80', 'Fearzone48_2018.z80', 'AYTracker.z80', 'Melody Master.z80',..., 'ZX Poker.z80']

Thanks for that!


TST: special.fdtri: remove test xfail after translation to C++

Reference issue
Closes gh-7931
What does this implement/fix?
There was an issue with fdtri (PPF of scipy.stats.f) on i686. After the translation to C++ (gh-20390), perhaps it is no longer relevant.

@steppi if the fix isn't obvious - or even if it is - it is probably not worth tracking this down if we will switch to Boost for fdtri (https://github.com/scipy/scipy/issues/20835#issuecomment-2336661225). Feel free to close.

Closing; now that ncfdtri uses Boost, we'll want to fdtri to use Boost anyway.


address page speed boost using compound index

after create Compound Index, the addr page get huge speed boost.
$ mongo
> use blockDB
> db.Transaction.createIndex({ from: 1, blockNumber: -1});
> db.Transaction.createIndex({ to: 1, blockNumber: -1});

for example, an addr page with ~250,000 txns

before : 300~600ms delay
after: less than 50~100ms delay

Credit: this method was introduced and confirmed by @turbobit (http://explorer.gonsmine.com)
https://www.ddengle.com/esn/7443710 (written in Korean)

just want to note here that geth itself now keeps an index of address -> txes via the RPC method geth_getAddressTransactions: https://github.com/ethereumproject/go-ethereum/pull/475


Updating card styling

Summary of changes
Related Issue
How to test (for features) / reproduce (for bugs)
Screenshots
Changes include

[ ] Bugfix (non-breaking change that solves an issue)
[ ] New feature (non-breaking change that adds functionality)
[ ] Documentation (explains but does not affect functionality)
[ ] Breaking change (change that is not backwards-compatible and/or changes current functionality)

Notes

please consider including a gif that reflects your feelings about this PR

It looks great @rweisberger ! the background image is just a little big and resource-heavy for your site to be rendered fast. I think the biggest our cards will display background image is around 800px, can you resize it to be 800px wide please? If you have a mac you can do so in Preview then go to Tools -> adjust Size.


Getting this running using vite

I am having trouble making this work using vite instead of webpack.
Uncaught SyntaxError: The requested module '/node_modules/.vite/deps/vuetify_lib.js?v=278ed383' does not provide an export named 'VDatetimePicker' (at app.vue?vue&type=template&lang.js:1:405)
I am using vuetify 2.5.8 and vite 2.6.13. I am able to get it to work by using it as my-datetime-picker. Is there something that says all v-... directives come from vuetify?
Any ideas?

https://github.com/m3h7/vuetify-datetime-picker/tree/vite-ts
Not 100% ready but it works for my vite ts project.

@mahiso how should I use your project in my vue.js app?


monitorCharacteristicForService value is fragmented

Prerequisites
Please answer the following questions for yourself before submitting an issue. YOU MAY DELETE THE PREREQUISITES SECTION.

[x] I am running the latest version
[x] I checked the documentation and found no answer
[x] I checked to make sure that this issue has not already been filed

Expected Behavior
Please describe the behavior you are expecting
monitorCharacteristicForService should receive updates from device completely and not break them into 2 fragments.
Current Behavior
What is the current behavior?
while using monitorCharacteristicForService to monitor UART protocol sent from device to app, sometimes the app receives an update but library seems to think its 2 fragments.
device sends 20 bytes converted to hex then to base 64
app converts the base 64 back to hex
but when app receives the update, it gets broken into 2 fragments.
Instead of receiving
QjJBWQE6AACwAQABAgMEBQYHCAk=
"42", "32", "41", "59", "01", "3A", "00", "00", "B0", "01", "00", "01", "02", "03", "04", "05", "06", "07", "08", "09"
The interprets it as
QjJB
"42", "32", "41", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00"
and
WQE6AACwAQABAgMEBQYHCAk=
"59", "01", "3A", "00", "00", "B0", "01", "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "00", "00", "00"
Steps to Reproduce &  Context
Testing ON DEVICE, IOS, with proprietary BLE device.
Since device is an inhouse prototype that I can't share, I can only share a few code blocks pertaining to the UART monitor and the parsing
this is the subscription
subscribeToUART = (id: string) => {
      // subscribe to UART char

      const device = this.findDeviceInState(id);

      if (!device) {
        return false;
      }

      this.uartSubscription = device.monitorCharacteristicForService(
        UART_UUID,
        RX_UUID,
        this.onUARTSubscriptionUpdate);
    }

this is the onUpdate
onUARTSubscriptionUpdate = async (error: any, characteristics: any) => {

      if (error) {
        console.log(error);
      } else if (characteristics) {
        console.log('onUARTSubscriptionUpdate', characteristics);

        this.handleMsg(characteristics.deviceID, characteristics.value);

      }

    }

this is the parser
handleMsg = async (deviceID: string, msg: string) => {
     const bytes = stringToBytes(Base64.atob(msg));
      const hexArray = this.buildPayloadWithPadding(base64toHEX(msg), 20);
      console.log('hexArray', hexArray);
}

FYI fragment issue happens kind of random, no way to predict when will it happen or under what conditions. Have not been able to find any pattern to this. Xcode logs does not show any errors

From xcode logs, i did observe logs overlapping
[RxBLEKit|DEBG|20:10:26.251]: Peripheral(uuid: FCCDB1D5-6FEF-F07B-2E6D-9D269040D849, name: Optional("BMMPR")) writeValue(
[RxBLEKit|DEBG|20:10:26.324]: Peripheral(uuid: FCCDB1D5-6FEF-F07B-2E6D-9D269040D849, name: Optional("BMMPR")) didWriteValueFor(for:Characteristic(uuid: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E, id:<PHONE_NUMBER>4),
[RxBLEKit|DEBG|20:10:36.438]: Peripheral(uuid: FCCDB1D5-6FEF-F07B-2E6D-9D269040D849, name: Optional("BMMPR")) didUpdateValueFor(for:Characteristic(uuid: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, id:<PHONE_NUMBER>8),
[RxBLEKit|DEBG|20:10:36.523]: Peripheral(uuid: FCCDB1D5-6FEF-F07B-2E6D-9D269040D849, name: Opt[RxBLEKit|DEBG|20:10:36.655]: Peripheral(uuid: FCCDB1D5-6FEF-F07B-2E6D-9D269040D849, name: Optional("BMMPR")) didWriteValueFor(for:Characteristic(uuid: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E, id:<PHONE_NUMBER>4),
[RxBLEKit|DEBG|20:10:46.625]: Peripheral(uuid: FCCDB1D5-6FEF-F07B-2E6D-9D269040D849, name: Optional("BMMPR")) didUpdateValueFor(for:Characteristic(uuid: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, id:<PHONE_NUMBER>8),
[RxBLEKit|DEBG|20:10:46.763]: Peripheral(uuid: FCCDB1D5-6FEF-F07B-2E6D-9D269040D8[RxBLEKit|DEBG|20:10:46.842]: Peripheral(uuid: FCCDB1D5-6FEF-F07B-2E6D-9D269040D849, name: Optional("BMMPR")) didWriteValueFor(for:Characteristic(uuid: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E, id:<PHONE_NUMBER>4),
[RxBLEKit|DEBG|20:10:56.774]: Peripheral(uuid: FCCDB1D5-6FEF-F07B-2E6D-9D269040D849, name: Optional("BMMPR")) didUpdateValueFor(for:Characteristic(uuid: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, id:<PHONE_NUMBER>8),
[RxBLEKit|DEBG|20:10:56.777]: Peripheral(uuid: FCCDB1D5-6FEF-F07B-2E6D-9D269040D849, name: Optional("BMMPR")) didUpdateValueFor(for:Characteristic(uuid: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, id:<PHONE_NUMBER>8),
[RxBLEKit|DEBG|20:10:56.802]: Peripheral(uuid: FCCDB1D5-6FEF-F07B-2E6D-9D269040[RxBLEKit|DEBG|20:10:56.846]: Peripheral(uuid: FCCDB1D5-6FEF-F07B-2E6D-9D269040D849, name: Optional("BMMPR")) didWriteValueFor(for:Characteristic(uuid: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E, id:<PHONE_NUMBER>4),

1 more set of logs from xcode
[RxBLEKit|DEBG|20:49:03.946]: Peripheral(uuid: FCCDB1D5-6FEF-F07B-2E6D-9D269040D849, name: Optional("BMMPR")) didUpdateValueFor(for:Characteristic(uuid: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, id:<PHONE_NUMBER>2),
value: Optional("42324159019b0000"),
error: nil)
[RxBLEKit|DEBG|20:49:03.982]: Peripheral(uuid: FCCDB1D5-6FEF-F07B-2E6D-9D269040D849, name: Optional("BMMPR")) didUpdateValueFor(for:Characteristic(uuid: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, id:<PHONE_NUMBER>2),
value: Optional("b5493cf9252f9a9b9c9d9e9f"),
error: nil)

And this is from the device

42 32 41 59 01 9B 00 00 B5 49 3C F9 25 2F 9A 9B 9C 9D 9E 9F ```

For some reason, ble stack received that TX from above and it got fragmented into 2

Some more interesting results, i intercepted this message here
value: Optional("42"),
error: nil)
[RxBLEKit|DEBG|21:11:52.353]: Peripheral(uuid: FCCDB1D5-6FEF-F07B-2E6D-9D269040D849, name: Optional("BMMPR")) didUpdateValueFor(for:Characteristic(uuid: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, id:<PHONE_NUMBER>0),
value: Optional("324159016b0000b57b1ca4b809babbbcbdbebf"),
error: nil)```

Which if you combine the fragment, you get `42324159016b0000b57b1ca4b809babbbcbdbebf`

However, on RN, i got base64 msg of `Qg==` and `MkFZAWsAALV7HKS4Cbq7vL2+vw==`

When you add those 2 together, you get `Qg==MkFZAWsAALV7HKS4Cbq7vL2+vw==` which in hex becomes
`"42", "10", "40", "32", "41", "59", "01", "6B", "00", "00", "B5", "7B", "1C", "A4", "B8", "09", "BA", "BB", "BC", "BD"`

It seems that when BLE stack received the msg its correct but when it passed it to RN it added extra characters at the back

You can't concatenate and then decode Base64 strings. You will get the wrong results due to padding, which is added in the end.

Additionally, based on the following log:
[RxBLEKit|DEBG|20:49:03.946]: Peripheral(uuid: FCCDB1D5-6FEF-F07B-2E6D-9D269040D849, name: Optional("BMMPR")) didUpdateValueFor(for:Characteristic(uuid: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, id:<PHONE_NUMBER>2),
value: Optional("42324159019b0000"),
error: nil)
[RxBLEKit|DEBG|20:49:03.982]: Peripheral(uuid: FCCDB1D5-6FEF-F07B-2E6D-9D269040D849, name: Optional("BMMPR")) didUpdateValueFor(for:Characteristic(uuid: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, id:<PHONE_NUMBER>2),
value: Optional("b5493cf9252f9a9b9c9d9e9f"),
error: nil)

I think that it is your device, who fragments messages, which are sent to the iOS app. To be absolutely sure, you should sniff packets coming over the radio.

@Cierpliwy
Thanks for the response, I did find the concat issue and started to concat as bytearray instead, that solved the parsing.
And I also loaded the app on android and had SIMILAR results of fragmented msgs, kind of determined the issue MUST be with the device, not with PLX.
Thanks for bouncing the ideas hehe


refactor set_ids() to use enumerate and/or list comprehension

When able, change DisjointSet.Set_ids() to use enumerate and/or list comprehension.
enumerate():
...
for i, p in enumerate(self.parents):
     if i == p:
        ...

list comprehension:
return List[Int](i for i, p in enumerate(self.parents) if i == p)

Of note: we can't do this yet. I am going to add a "blocked" tag. This task is blocked, awaiting more features in core Mojo language.


Added CSV framework and an article on vapor 3.

Project Name: CSV Framework
Project URL: https://github.com/skelpo/CSV
Project Description: A simple CSV parser written specifically for and with Vapor.
Why it should be added to awesome-vapor:
[ ] Project has at least 15 stars (if it's a GitHub project)
[x] Project supports Swift 4
[x] Project supports at least Vapor 2
[ ] I used correctly sized dash and ended the entry with a full stop 🤓

          2 Errors

:no_entry_sign:
Please make sure your submission uses correctly sized dash and ends with a full stop

:no_entry_sign:
Found 2 link issues

          1 Warning

:warning:
Too many changes (when adding, please keep it to one project per Pull Request)

Link issues by awesome_bot

Line
Status
Link

71
404
https://bygri.github.io/2018/01/25/vapor-2-with-docker.html

72
404
https://bygri.github.io/2018/01/25/vapor-3-with-docker.html

  Generated by :no_entry_sign: Danger

I fixed the two link issues the bot was complaining about in PR #18 so you can resubmit if you wish – or I can do so myself a bit later :)

@Cellane thanks! I was a little confused. I accidentally added two links with one PR, next time I'll do it better ;)

@proggeramlug It's totally fine, most of the warnings are just suggestions for now to see what sticks, what makes sense and what actually works for the repository in the long run. I wouldn't want to pester people endlessly (perhaps except when it's typography related 🤣) and chase everyone away 😅
Thanks for your contribution, at any rate!

Merged, thank you for your contribution! 🙇


Update Getting-Started.md

typo fix (cna -> can) and I believe legacy copy/pasta (RichTextKit -> PrintingKit) updates in Getting Started.

Thank you @heckj 🙏


boyne update

Tried to make a PR for this but was denied.
Anyways the fix for the Boyne resorts is below.
Tested on local instance and [brighton, big-sky, loon, sugarloaf, sunday-river] are all
working.
module.exports = {   selector: 'div.liftStatus-lift-icon',   parse: {     name: '+/0',     status: {       child: '0',       attribute: 'alt'     }   } };

Thanks. It's released now.
What do you mean by:

Tried to make a PR for this but was denied.

In any case: I am totally cool with people sending me references to any git repo - does not have to be on github - any git request-pullworks. Or even sending me a patch with git format-patch.


Correct typos and grammar issues in Javadoc

Some minor typos and suchlike that I spotted while reading through the codebase.

Coverage remained the same at 100.0% when pulling 194dd039c37d30b68dc4fc61a0d9354fecfc9dd9 on richdouglasevans:typos into 6ad132b1ceae8c91d30115bd8e37142947cce8cd on greghaskins:master.

:+1:

Cheers for the :+1: Ash! I'm hoping to make pull requests with more meat in the near future :smile:

Looks great, thanks @richdouglasevans !


code-server: 4.12.0 -> 4.13.0

Description of changes

Things done

Built on platform(s)

[x] x86_64-linux
[ ] aarch64-linux
[ ] x86_64-darwin
[ ] aarch64-darwin

[ ] For non-Linux: Is sandbox = true set in nix.conf? (See Nix manual)
[ ] Tested, as applicable:

NixOS test(s) (look inside nixos/tests)
and/or package tests
or, for functions and "core" functionality, tests in lib/tests or pkgs/test
made sure NixOS tests are linked to the relevant packages

[ ] Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
[ ] Tested basic functionality of all binary files (usually in ./result/bin/)
23.05 Release Notes (or backporting 22.11 Release notes)

[ ] (Package updates) Added a release notes entry if the change is major or breaking
[ ] (Module updates) Added a release notes entry if the change is significant
[ ] (Module addition) Added a release notes entry if adding a new NixOS module

[ ] Fits CONTRIBUTING.md.

@GrahamcOfBorg build code-server

It depends on insecure nodejs 16, thus ofborg refuses to build it, can we bump to some later version?

Code-server doesn't build with nodejs 18 yet
Tracking upstream here https://github.com/coder/code-server/issues/6230

Closed in favor of #237986


Floating windows not respecting g:fzf_colors?

[x] I have read through the manual page (man fzf)
[x] I have the latest version of fzf
[x] I have searched through the existing issues

Info

OS

[ ] Linux
[x] Mac OS X
[ ] Windows
[ ] Etc.

Shell

[ ] bash
[x] zsh
[ ] fish

Problem / Steps to reproduce
With the following floating window fzf_layout and fzf_colors settings, it's not rendering colours within the same as if I had not setup a floating window...
let g:fzf_layout = { 'window': { 'width': 1, 'height': 0.5, 'yoffset': 1, 'border': 'horizontal' } }

let g:fzf_colors = {
  \ 'fg':      ['fg', 'Normal'],
  \ 'bg':      ['bg', 'Normal'],
  \ 'hl':      ['fg', 'Label'],
  \ 'fg+':     ['fg', 'CursorLine', 'CursorColumn', 'Normal'],
  \ 'bg+':     ['bg', 'CursorLine', 'CursorColumn'],
  \ 'hl+':     ['fg', 'Label'],
  \ 'info':    ['fg', 'Comment'],
  \ 'border':  ['fg', 'Ignore'],
  \ 'prompt':  ['fg', 'Function'],
  \ 'pointer': ['fg', 'Statement'],
  \ 'marker':  ['fg', 'Conditional'],
  \ 'spinner': ['fg', 'Label'],
  \ 'header':  ['fg', 'Comment'] }

Example without floating window:

Example with floating window:

And my current highlight settings for Label there:

@junegunn, The thing that confuses me most is the color inconsistency between the new window layout, and the default layout 🤔  Any thoughts to why this might be?

No idea, it works for me. Have you tested it on both Vim and Neovim? Is &termguicolors 0 or 1?

Just Vim, not a Neovim user.  Also &termguicolors is 0 for me.

Fwiw, these are my fzf vim customizations.  Not sure if the way I'm configuring my colours sheds any light?

@junegunn Could it have something to do with fzf's buffer filetype/syntax differing between the default layout and floating window layout?  (Not sure if that's a thing, or if I'm out in left field)

@junegunn Could it have something to do with fzf's buffer filetype or colorscheme differing between the default layout and floating window layout?  (Not sure if that's a thing, or if I'm out in left field)

Open up a terminal buffer (:terminal) inside Vim, start fzf (or any other program that prints colors) and see if the colors look different when you run it outside of Vim.

@junegunn Weird, in :terminal, fzf is rendering different colours than even the two above examples.  Here's a gif screencast of all three...

Notice the highlighted search term is yellow in the default fzf layout, brownish-orange in the floating window layout, and light green within :terminal.

Yeah, for some reason, built-in terminals of Vim and Neovim both use their own palette for ANSI base colors. See :help terminal-size-color to find out how to configure the colors to match the colors of your terminal emulator theme. But better yet, you might want to this as an opportunity to set up 24-bit colors for the terminal (&termguicolors) so fzf looks identical regardless of the color palette.
:set termguicolors
:echo fzf#wrap()
{'options': '''--color=bg+:#3F3F3F,bg:#4B4B4B,border:#6B6B6B,spinner:#98BC99,hl:#719872,fg:#D9D9D9,header:#719872,info:#BDBB72,pointer:#E12672,marker:#E17899,fg+:#D9D9D9,prompt:#98B
EDE,hl+:#98BC99''  --expect=ctrl-v,ctrl-x,ctrl-t', 'sink*': function('129'), 'window': {'width': 0.9, 'height': 0.6}, '_action': {'ctrl-v': 'vsplit', 'ctrl-x': 'split', 'ctrl-t': 't
ab split'}}

:set notermguicolors
:echo fzf#wrap()
{'options': '''--color=bg+:236,bg:237,border:240,spinner:108,hl:65,fg:252,header:65,info:143,pointer:161,marker:168,fg+:252,prompt:110,hl+:108''  --expect=ctrl-v,ctrl-x,ctrl-t', 'si
nk*': function('131'), 'window': {'width': 0.9, 'height': 0.6}, '_action': {'ctrl-v': 'vsplit', 'ctrl-x': 'split', 'ctrl-t': 'tab split'}}

@junegunn Forget terminal for a moment though.  It does not bother me that fzf in Vim renders differently than fzf in my terminal, I'm totally fine with that.  I'm specifically wondering why with these g:fzf_colors settings:
let g:fzf_colors = {
  \ 'fg':      ['fg', 'Normal'],
  \ 'bg':      ['bg', 'Normal'],
  \ 'hl':      ['fg', 'Label'],
  \ 'fg+':     ['fg', 'CursorLine', 'CursorColumn', 'Normal'],
  \ 'bg+':     ['bg', 'CursorLine', 'CursorColumn'],
  \ 'hl+':     ['fg', 'Label'],
  \ 'info':    ['fg', 'Comment'],
  \ 'border':  ['fg', 'Ignore'],
  \ 'prompt':  ['fg', 'Function'],
  \ 'pointer': ['fg', 'Statement'],
  \ 'marker':  ['fg', 'Conditional'],
  \ 'spinner': ['fg', 'Label'],
  \ 'header':  ['fg', 'Comment'] }

I see different colors with and without the following g:fzf_layout floating window config:
let g:fzf_layout = { 'window': { 'width': 1, 'height': 0.5, 'yoffset': 1, 'border': 'top' } }

For example, everywhere else in Vim, Label renders as yellow, including where I'm using it within g:fzf_colors.  However, as soon as I enable the new floating window mode on g:fzf_layout, not all of my g:fzf_colors settings are respected?  And how is termguicolors relevant?

:echo fzf#wrap() and you'll see the --color options generated according to g:fzf_colors. An ANSI color code less than 16 is a base color that can be rendered differently.
fzf on regular Vim by default doesn't start in a terminal buffer. It starts below Vim using --height option (related #1860). When you configure it to use a pop-up window, however, it's no longer possible to use --height option, and fzf has to start in a terminal buffer. So that's where the color palette matters.
If &termguicolors is used, it will generate 24-bit colors (e.g. --color=bg+:#3F3F3F), which should appear the same regardless of the color palette.

@junegunn Ah this is starting to make more sense.  That said, why would my fzf hl render as green when fzf is run manually in a :Terminal window, but orangey-brown when fzf is running via a terminal buffer for floating popups.  Shouldn't those at least render colors consistently with each other, as both are terminal output within Vim?


Adds a Num.restrictToInterval function

This PR is the result from this issue and this zulip thread.

We don't run expects tests for Num.roc yet. I need to do #6289 before we merge this.


Please clarify what unit Mi is or describes

As the title says, please clarify/explain what the unit Mi means. Thanks

Document Details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

ID: a445f8cc-6581-ad43-1dba-719a94eda81a
Version Independent ID: 31280746-d8de-91b4-d430-91693c2e869d
Content: Concepts - Kubernetes basics for Azure Kubernetes Services (AKS) - Azure Kubernetes Service
Content Source: articles/aks/concepts-clusters-workloads.md
Service: container-service
GitHub Login: @mlearned
Microsoft Alias: mlearned

@sp4rc Thanks for the feedback! We are currently investigating and will update you shortly.

You are asking about what is a "millicore?"  .. correct?
See:  https://docs.microsoft.com/en-us/azure/container-instances/container-instances-monitor
we can add a cross-link in the doc as it's missing there

You are asking about what is a "millicore?" .. correct?

Exactly. A cross-link would be helpful.

@mlearned Thanks for providing the details and acknowledging the feedback on the doc referencing part.
@sp4rc Thanks for responding back. Hope the provided information is helpful.


update links in traffic management

Several reference links have moved on istio.io/docs . Minor corrections to markdown formatting to match best practices.

many links broken besides exercise-6 content. closing PR and will submit more fixes at later time


refactor ipcinfo

remove request for donation
rename Help() to print_usage()
remove old syntax support
add an option for version
fix typos

Thank you for your valuable contribution!


Broken overflow on fixed width.

If select2 input has a limited with, the value overflow is broken as you can see on the following screenshot:

I use the following code to instanciate select2:
select.select2({
    width: '100%',
    placeholder: ' ',
    dropdownAutoWidth: true,
    minimumResultsForSearch: 10,
    allowClear: allowClearEnabled
});

Don't know how to fix this issue, any idea?
Thanks.

I'm using 4.0.0b3.
Whenever I selected a very long text, the overflow was not hidden like you describe. I had to add the following css to hide it:
.select2-selection--single {
  overflow: hidden;
  text-overflow: ellipse;
}

disclaimer: I'm a select2 neophyte.

Adding whitespace: nowrap to ..select2-selection__rendered (for single only) fixed the issue.

It works. Thanks. Sorry about the duplicate

I'm sorry but this issue is not completly fixed:

As you can see, the clear label is broken.
I'm using select2 4.0.0-rc.1

@Soullivaneuh That issue is slightly different and is being tracked in https://github.com/select2/select2/issues/3089.

I think the whitespace: nowrap is causing issue on mobile
So if you add a width: 50% style in-line to the parent container, the control will  will respect that width up until the control is less than the in-line style width of the option text, in this case < 50% of the option width

I have same trouble with you, then I found a way to fix it.
in view, I wrote this,
<select class="select2" data-width="100%" multiple id="xref" name="xref[]"></select>
then in js, I wrote this
$("#xref").select2({      containerCssClass: 'wrap' });
and add css in select2 css like this:
.wrap.select2-selection--multiple { height: 100% }
.select2-container .wrap.select2-selection--multiple  .select2-selection__rendered li { word-wrap: break-word; text-overflow: inherit; white-space: normal !important }
hope this will help you ^^