Переменные не обновляются в обратном вызове

У меня есть код для определения поведения модели позиции, установленной в файле привязки для stageros. Я хочу отслеживать его текущую позицию в мире в переменных px py и ptheta, подписавшись на тему odom для сообщений одометрии, отправляемых stageros. Как это:

ros::Subscriber RobotOdometry_sub = n.subscribe<nav_msgs::Odometry>("robot_0/odom",1000,&Robot::ReceiveOdometry,this);

Который помещается в конструктор для объекта Robot. Тогда обратный вызов выглядит следующим образом:

void Robot::ReceiveOdometry(nav_msgs::Odometry msg)
{
    //This is the call back function to process odometry messages coming from Stage.
    px = initialX + msg.pose.pose.position.x;
    py = initialY + msg.pose.pose.position.y;
    ptheta = angles::normalize_angle_positive(asin(msg.pose.pose.orientation.z) * 2);
    ROS_INFO("x odom %f y odom %f theta %f", px, py, ptheta);
}

Этот обратный вызов, кажется, вызывается без проблем. Значения px, py и ptheta, напечатанные обратным вызовом, также верны и соответствуют их текущему положению в мире. Проблема возникает в других функциях:

void Robot::OtherFunction() {
    while (ros::ok())
    {
        ros::spinOnce();
        ROS_INFO("x %f y %f theta %f", px, py, ptheta);
    }
}

Это всего лишь пример, но по какой-то причине значения px, py и ptheta, напечатанные из другой функции, всегда кажутся застрявшими на начальных значениях px, py и ptheta. Несмотря на то, что обратный вызов ReceiveOdometry также постоянно печатает правильные значения. Значения px, py, ptheta различны, как если бы для каждой переменной было два разных значения.

ROS_INFO от ReceiveOdometry правильно печатает текущую позицию.

ROS_INFO из OtherFunction печатает начальные позиции и вообще не меняется, хотя px, py и ptheta постоянно устанавливаются в ReceiveOdometry.

Кто-нибудь знает, почему изменения в px, py и ptheta в обратном вызове ReceiveOdometry не переносятся в OtherFunction? Надеюсь, этот вопрос имеет смысл.

Спасибо.


person Jigglypuff    schedule 16.08.2012    source источник
comment
Вы уверены, что это тот же экземпляр Robot? Напечатайте значение this, чтобы быть уверенным.   -  person hmjd    schedule 16.08.2012
comment
@hmjd Да, это тот же экземпляр Robot.   -  person Jigglypuff    schedule 16.08.2012
comment
Это может быть проблема видимости потока. Предположительно, обратный вызов вызывается в потоке, отличном от потока OtherFunction()?   -  person hmjd    schedule 16.08.2012
comment
@hmjd Извините, но я не знаю. Хотя может быть и так.   -  person Jigglypuff    schedule 16.08.2012
comment
@hmjd Я использую CMakeFile, созданный с помощью пакета ROS.   -  person Jigglypuff    schedule 16.08.2012
comment
Это, безусловно, похоже на то, что классическое «это» неправильно распространяется вокруг подписки/обратного вызова, как это было предложено другими. Мы видим, что вы передали «это» при подписке, но мы не можем видеть, как оно сохраняется/передается и, следовательно, как вызовы ReceiveOdometry выполняются для правильного объекта.   -  person Martin James    schedule 16.08.2012


Ответы (2)


Распечатайте и проверьте это в обеих функциях. Вы будете использовать два разных объекта.

person olivecoder    schedule 16.08.2012

Возможно, происходит какая-то оптимизация, и переменные не считываются из памяти, а хранятся в кеше, поскольку они не изменяются внутри цикла while. Если это так, объявление их как volatile помогло бы.

О ключевом слове volatile

person pgorczak    schedule 20.08.2012