Подглава 2.5.9 Узел контроллера трекера лица

Как мы уже видели, узел контроллера трекера лица отвечает за управление сервоприводом Dynamixel в соответствии с положением центроида лица. Давайте разберемся в коде этого узла, который находится по адресу face_tracker_control/src/face_tracker_controller.cpp.

Основные заголовки ROS, включенные в этот код, следующие. Здесь заголовок Float64 используется для хранения сообщения значения позиции контроллеру:

#include "ros/ros.h"
#include "std_msgs/Float64.h" 
#include <iostream>

Следующие переменные содержат значения параметров из servo_param.yaml:

int servomaxx, servomin,screenmaxx, center_offset, center_left, center_right;
float servo_step_distancex, current_pos_x;

Следующие заголовки сообщения std_msgs::Float64 предназначены для хранения начальной и текущей позиции контроллера, соответственно. Контроллер принимает только этот тип сообщения:

std_msgs::Float64 initial_pose; 
std_msgs::Float64 current_pose;

Это обработчик издателя для публикации команд положения в контроллере:

ros::Publisher dynamixel_control;

Переходя к функции main() кода, вы можете увидеть следующие строки кода. Первая строка - это подписчик /face_centroid, у которого есть значение centroid, и когда значение приходит в topic, оно вызывает функцию face_callback ():

ros::Subscriber number_subscriber = node_obj.subscribe("/face_centroid",10,face_callback);

Следующая строка инициализирует дескриптор издателя, в котором значения будут опубликованы в разделе /​pan_controller/command:

dynamixel_control = node_obj.advertise<std_msgs::Float64> ("/pan_controller/command",10);

Следующий код создает новые ограничения вокруг фактического центра изображения. Это будет полезно для получения приблизительной центральной точки изображения:

center_left = (screenmaxx / 2) - center_offset; 
center_right = (screenmaxx / 2) + center_offset;

Вот функция обратного вызова, выполняемая при получении значения центроида, поступающего через раздел /face_centroid. Этот обратный вызов также имеет логику для перемещения Dynamixel для каждого значения центроида.

В первом разделе значение x в центроиде сравнивается с center_left, а если оно слева, оно просто увеличивает положение сервоконтроллера. Он будет публиковать текущее значение, только если текущая позиция находится в пределах лимита. Если он находится в пределе, то он опубликует текущую позицию в контроллере. Логика одинакова для правой стороны: если грань находится на правой стороне изображения, это уменьшит положение контроллера.

Когда камера достигает центра изображения, она останавливается и ничего не делает, и это то, чего мы тоже хотим. Этот цикл повторяется, и мы получим непрерывное отслеживание:

void track_face(int x,int y)
{
if (x < (center_left)){
current_pos_x += servo_step_distancex; 
current_pose.data = current_pos_x;
if (current_pos_x < servomaxx and current_pos_x > servomin ){ dynamixel_control.publish(current_pose);
  }
}
else if(x > center_right){ current_pos_x -= servo_step_distancex; current_pose.data = current_pos_x;
if (current_pos_x < servomaxx and current_pos_x > servomin ){ dynamixel_control.publish(current_pose);
  }
}
else if(x > center_left and x < center_right){; 
  }
}

Last updated

Was this helpful?