Unfortunately, I am not familiar with it to the required extent, I am learning programming in C/C++ through practical experience 
Your explanation of the pointers and links is very clear, thank you for the clarification.
In the end, in a few hours I wrote a function for drawing lines and text:
void create_line_v5(lv_obj_t *canvas, int x1, int y1, int x2, int y2, lv_color_t color, int thickness, bool text_label = false) {
// Create a line description
lv_draw_line_dsc_t line_dsc;
lv_draw_line_dsc_init(&line_dsc);
line_dsc.color = color; // Set the line color
line_dsc.width = thickness; // Set the line thickness
line_dsc.round_end = 1; // Round the end of the line
line_dsc.round_start = 1; // Round the beginning of the line
// Set the start and end points of the line
line_dsc.p1.x = x1; // Start point on X axis
line_dsc.p1.y = y1; // Start point on Y axis
line_dsc.p2.x = x2; // End point on X axis
line_dsc.p2.y = y2; // End point on Y axis
lv_draw_label_dsc_t label_dsc_left;
lv_draw_label_dsc_init(&label_dsc_left);
lv_area_t coords_left = {x1 - 22, y1 - 10, x2 - 22, y2 - 10};
lv_draw_label_dsc_t label_dsc_right;
lv_draw_label_dsc_init(&label_dsc_right);
lv_area_t coords_right = {x1 + 82, y1 - 10, x2 + 82, y2 - 10};
if (text_label == true) {
// label_dsc_left.color = lv_color_hex(0xFFFFFF); // Set text color to white
label_dsc_left.color = color;
label_dsc_left.font = &lv_font_montserrat_18;
label_dsc_left.decor = LV_TEXT_DECOR_NONE;
label_dsc_left.text = "10";
// label_dsc_left.color = lv_color_hex(0xFFFFFF); // Set text color to white
label_dsc_right.color = color;
label_dsc_right.font = &lv_font_montserrat_18;
label_dsc_right.decor = LV_TEXT_DECOR_NONE;
label_dsc_right.text = "10";
}
// Initialize the canvas layer
lv_layer_t layer;
lv_canvas_init_layer(canvas, &layer);
// Draw a line on the canvas
lv_draw_line(&layer, &line_dsc);
if (text_label == true) {
// Draw text/label on the canvas
lv_draw_label(&layer, &label_dsc_left, &coords_left);
lv_draw_label(&layer, &label_dsc_right, &coords_right);
}
// Finish working with the canvas layer
lv_canvas_finish_layer(canvas, &layer);
}
And the function code itself, which uses the function above to display the whole picture:
void pitch_scale_v5(int roll_deg, int pitch_deg)
{
// Define canvas size and line thickness
// Doesn't load when LV_MEM_SIZE is low, less than 128 - we need to think about how to solve the problem for ESP32
#define CANVAS_PITCH_SCALE_WIDTH 120
#define CANVAS_PITCH_SCALE_HEIGHT 180
#define PITCH_LINE_THICKNESS 2
#define PITCH_LINE_CENTER CANVAS_PITCH_SCALE_HEIGHT / 2
/*Create a buffer for the canvas*/
LV_DRAW_BUF_DEFINE_STATIC(draw_pitch_scale_buf, CANVAS_PITCH_SCALE_WIDTH, CANVAS_PITCH_SCALE_HEIGHT, LV_COLOR_FORMAT_ARGB8888); // does not load at all on a real device
// LV_DRAW_BUF_DEFINE_STATIC(draw_pitch_scale_buf, CANVAS_PITCH_SCALE_WIDTH, CANVAS_PITCH_SCALE_HEIGHT, LV_COLOR_FORMAT_RGB565); // no way to set transparency
// LV_DRAW_BUF_DEFINE_STATIC(draw_pitch_scale_buf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_AL88); // black and white image
// LV_DRAW_BUF_DEFINE_STATIC(draw_pitch_scale_buf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_ARGB8565); // not displayed at all on a real device
// LV_DRAW_BUF_DEFINE_STATIC(draw_pitch_scale_buf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_RGB565A8); // the image falls apart
LV_DRAW_BUF_INIT_STATIC(draw_pitch_scale_buf);
/*Create a canvas and initialize its palette*/
lv_obj_t * canvas_pitch_line = lv_canvas_create(lv_screen_active());
lv_canvas_set_draw_buf(canvas_pitch_line, &draw_pitch_scale_buf);
// canvas is visible
// lv_canvas_fill_bg(canvas_pitch_line, lv_color_hex3(0xccc), LV_OPA_COVER);
// makes the canvas layer transparent
lv_canvas_fill_bg(canvas_pitch_line, lv_color_hex3(0xccc), LV_OPA_TRANSP);
// centers the entire canvas in the center of the display
lv_obj_center(canvas_pitch_line);
lv_obj_set_pos(canvas_pitch_line, 0, 0); // X->, Y-â
// Draw lines using the new function
// Positive
create_line_v5(canvas_pitch_line, (CANVAS_PITCH_SCALE_WIDTH / 2) - 25, PITCH_LINE_CENTER - 120, (CANVAS_PITCH_SCALE_WIDTH / 2) + 25, PITCH_LINE_CENTER - 120, lv_color_hex(0xFFFFFF), PITCH_LINE_THICKNESS); // label 15, width 50
create_line_v5(canvas_pitch_line, (CANVAS_PITCH_SCALE_WIDTH / 2) - 15, PITCH_LINE_CENTER - 100, (CANVAS_PITCH_SCALE_WIDTH / 2) + 15, PITCH_LINE_CENTER - 100, lv_color_hex(0xFFFFFF), PITCH_LINE_THICKNESS); // label 12_5, width 30
create_line_v5(canvas_pitch_line, (CANVAS_PITCH_SCALE_WIDTH / 2) - 40, PITCH_LINE_CENTER - 80, (CANVAS_PITCH_SCALE_WIDTH / 2) + 40, PITCH_LINE_CENTER - 80, lv_color_hex(0xFFFFFF), PITCH_LINE_THICKNESS, true); // label 10, width 80
create_line_v5(canvas_pitch_line, (CANVAS_PITCH_SCALE_WIDTH / 2) - 15, PITCH_LINE_CENTER - 60, (CANVAS_PITCH_SCALE_WIDTH / 2) + 15, PITCH_LINE_CENTER - 60, lv_color_hex(0xFFFFFF), PITCH_LINE_THICKNESS); // label 7_5, width 30
create_line_v5(canvas_pitch_line, (CANVAS_PITCH_SCALE_WIDTH / 2) - 25, PITCH_LINE_CENTER - 40, (CANVAS_PITCH_SCALE_WIDTH / 2) + 25, PITCH_LINE_CENTER - 40, lv_color_hex(0xFFFFFF), PITCH_LINE_THICKNESS); // label 5, width 50
create_line_v5(canvas_pitch_line, (CANVAS_PITCH_SCALE_WIDTH / 2) - 15, PITCH_LINE_CENTER - 20, (CANVAS_PITCH_SCALE_WIDTH / 2) + 15, PITCH_LINE_CENTER - 20, lv_color_hex(0xFFFFFF), PITCH_LINE_THICKNESS); // label 2_5, width 30
// Negative
create_line_v5(canvas_pitch_line, (CANVAS_PITCH_SCALE_WIDTH / 2) - 15, PITCH_LINE_CENTER + 20, (CANVAS_PITCH_SCALE_WIDTH / 2) + 15, PITCH_LINE_CENTER + 20, lv_color_hex(0xFFFFFF), PITCH_LINE_THICKNESS); // label 2_5, width 30
create_line_v5(canvas_pitch_line, (CANVAS_PITCH_SCALE_WIDTH / 2) - 25, PITCH_LINE_CENTER + 40, (CANVAS_PITCH_SCALE_WIDTH / 2) + 25, PITCH_LINE_CENTER + 40, lv_color_hex(0xFFFFFF), PITCH_LINE_THICKNESS); // label 5, width 50
create_line_v5(canvas_pitch_line, (CANVAS_PITCH_SCALE_WIDTH / 2) - 15, PITCH_LINE_CENTER + 60, (CANVAS_PITCH_SCALE_WIDTH / 2) + 15, PITCH_LINE_CENTER + 60, lv_color_hex(0xFFFFFF), PITCH_LINE_THICKNESS); // label 7_5, width 30
create_line_v5(canvas_pitch_line, (CANVAS_PITCH_SCALE_WIDTH / 2) - 40, PITCH_LINE_CENTER + 80, (CANVAS_PITCH_SCALE_WIDTH / 2) + 40, PITCH_LINE_CENTER + 80, lv_color_hex(0xFFFFFF), PITCH_LINE_THICKNESS, true); // 1label 10, width 80
create_line_v5(canvas_pitch_line, (CANVAS_PITCH_SCALE_WIDTH / 2) - 15, PITCH_LINE_CENTER + 100, (CANVAS_PITCH_SCALE_WIDTH / 2) + 15, PITCH_LINE_CENTER + 100, lv_color_hex(0xFFFFFF), PITCH_LINE_THICKNESS); // label 12_5, width 30
create_line_v5(canvas_pitch_line, (CANVAS_PITCH_SCALE_WIDTH / 2) - 25, PITCH_LINE_CENTER + 120, (CANVAS_PITCH_SCALE_WIDTH / 2) + 25, PITCH_LINE_CENTER + 120, lv_color_hex(0xFFFFFF), PITCH_LINE_THICKNESS); // label 15, width 50
lv_obj_set_style_transform_pivot_x(canvas_pitch_line, CANVAS_PITCH_SCALE_WIDTH / 2, LV_PART_MAIN);
lv_obj_set_style_transform_pivot_y(canvas_pitch_line, (CANVAS_PITCH_SCALE_HEIGHT / 2), LV_PART_MAIN);
// lv_obj_set_style_transform_rotation(canvas_pitch_line, 0 * 10, LV_PART_MAIN);
// lv_obj_set_style_transform_rotation(canvas_pitch_line, 10 * 10, LV_PART_MAIN);
// lv_obj_set_style_transform_rotation(canvas_pitch_line, 20 * 10, LV_PART_MAIN);
lv_obj_set_style_transform_rotation(canvas_pitch_line, -roll_deg * 10, LV_PART_MAIN);
}
For now this is the idea, all that remains is to animate it 
Tried to increment via timer function, but it doesnât work yet:
// Callback function for rotation
static void time_cb(lv_timer_t* t) {
lv_obj_t* gauge_moved = static_cast<lv_obj_t*>(lv_timer_get_user_data(t));
static int i = 0;
i = i++;
roll_deg = roll_deg + i;
}
void animator(void) {
lv_obj_t * gauge_moved;
// Create a timer to animate the gauge
lv_timer_create(time_cb, 1000, gauge_moved);
}
As far as I understand, you need to use LVGL
timers 
https://docs.lvgl.io/master/details/main-modules/timer.html
or rewrite them for freeRTOS
.