Обработчик сигнала с большим количеством параметров - PullRequest
0 голосов
/ 09 июля 2019

Я работаю с ROS Melodic и Gazebo 9.9.0 на Ubuntu 18.04.2 LTS.

Я хочу отправить роботу сообщение об остановке (твист со всеми нулями), когда пользователь убивает узел.

Чтобы обработать событие Ctrl. + C, я использую это:

/**
 * Override the default ros sigint handler to stop the robot when user press
 * Ctrl.+C.
 */
void sigintHandler(int sig)
{


  // All the default sigint handler does is call shutdown()
  ros::shutdown();
}

Но эта функция не позволяет передавать больше параметров (мне нужно передать cmd_vel_pub).

Я объявил этого издателя в основной функции:

int main(int argc, char **argv)
{
  ros::init(argc, argv, "astar_controller");

  ros::NodeHandle n;

  // Override the default ros sigint handler.
  // This must be set after the first NodeHandle is created.
  std::signal(SIGINT, sigintHandler);

  /**
   * Topic where we are going to publish speed commands.
   */
  ros::Publisher cmd_vel_pub = n.advertise<geometry_msgs::Twist>(cmdTopic, 1000);

  // More code...
}

Может быть, я могу объявить cmd_vel_pub глобальным.

Есть ли способ передать больше параметров в sigintHandler или мне нужно объявить его как глобальный?

1 Ответ

1 голос
/ 10 июля 2019

Существует ограниченный список функций, которые можно вызывать из обработчика сигнала, см. man signal-safety. По этой причине отправка сообщения Twist может быть невозможна из контекста обработчика сигнала.

Самостоятельная уловка часто используется для обработки сигнала вне контекста обработчика сигнала:

Поддерживать канал и выбирать для удобства чтения на входе канала. Внутри обработчика сигнала запишите байт (на всякий случай неблокирующий) на выход канала. Готово.

Кроме того, я рекомендую записать байт номера сигнала в канал, чтобы вы могли использовать один и тот же обработчик сигнала и канал для любого сигнала (если это необходимо).

Поток, который хочет обработать сигнал, должен дождаться, пока конец чтения канала станет читаемым, прочитать этот байт и обработать сигнал. Ожидание может быть выполнено с использованием цикла событий (например, select, epoll и т. Д.) Или блокирующего вызова read.

В качестве альтернативы вы можете использовать signalfd вместо трубы (см. Пример там). Или sigsuspend для блокировки и ожидания сигнала.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...