Skip to content

caret_trace#

caret_trace is a package who deliver the following feature during recording.

  1. Defining the tracepoints dedicated to CARET via function hooking
  2. Adding state management of tracepoints via function hooking for trace filtering and runtime recording
  3. Adding function of recording with sim_time

Class Structure#

uml diagram

Implementation of tracepoints with function hooking#

CARET adopts function hooking mainly for adding new trace points. On the other hand, existing tracepoints, which are built in ROS 2, are also re-defined by function hooking because CARET adds the function to manage tracepoint state.

Here is the pseudo code for hook functions.

void ros_trace_callback_start(TRACEPOINT_ARGS) {
  // Record trace data only if current callback is allowed to record
  if (controller.is_allowed(TRACEPOINT_ARGS)) {
    tracepoint(TRACEPOINT_ARGS); // LTTng tracepoint
  }
}

void ros_trace_XXX_init(TRACEPOINT_ARGS)
{
  // Wrapper function for tracepoint.
  // This function is executed with delay.
  // This function is executed either from the record at the end of this function
  // or from TraceNode's timer callback.
  // Duplicate data are resolved with caret_analyze.
  static auto record = [](TRACEPOINT_ARGS, now) {
    // Record trace data only if current callback is allowed to record
    if (controller.is_allowed(TRACEPOINT_ARGS)) {
      tracepoint(TRACEPOINT_ARGS, now); // LTTng tracepoint
    }
  };

  auto now = clock.now(); // Measure immediately after function call

  if (!data_container.is_assigned_XXX()) {
    data_container.assign_XXX(record);
  }

  // Store TRACEPOINT_ARGS in memory.
  data_container.store_XXX(TRACEPOINT_ARGS, now);

  record(TRACEPOINT_ARGS, now);
}

ros_trace_callback_start is an example of hook functions to trace callback start. It is a kind of trace points for collecting events related to application s behavior, and so called runtime trace point.

ros_trace_XXX_init is an example of hook function to get identification of application's component. It is expected to be called when application is launched and initialized. The trace point is categorized into initialization trace point.

A set of identifications such as a callback address or node name is given as TRACEPOINT_ARGS. Several kinds of initialization trace point are served, and each of them is attached to different kind of component; executor, node, callback, publisher, subscriber, and etc. For example, one is called to collect node's identification while another is called to collect publisher's identification.

Identifications collected from different trace points share same addresses or names as elements. By connecting such identifications by the same addresses or names, CARET is able to help you to find application's structure.

See Initialization trace points for details.

clock recorder#

CARET can select simulation time, represented as sim_time, for visualization. sim_time can be recorded by running the clock_recorder node, which adds trace points for sim_time recording.

ros2 caret trace --record-clock

ClockRecorder node wakes up per second and records a pair of sim_time and system time. The pair is used to convert system time to simulation time.