ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

You could do this several ways. Quick and dirty is to combine the GPS message callback and a Timer. Below you see that a timer is created that gets called at 10 Hz and uses the latest GPS data. It then resets the stored GPS data back to zeros until a new GPS message arrives. This will always print out zeros unless you have fresh GPS data.

Note that global variables are used here, but the link to the Timers page has examples of how to use a callback function for a Timer that is part of a class. Then, you could store the latest GPS data as class member variables.

#include <ros/ros.h>
#include <ros/time.h>
#include <gps_common/GPSFix.h>

using namespace std;

double g_latest_lat = 0.0;
double g_latest_lon = 0.0;

void timerCallback(const ros::TimerEvent& event)
{
    ROS_INFO("(lat, lon) = (%lf, %lf)", g_latest_lat, g_latest_lon);
    g_latest_lat = 0.0;
    g_latest_lon = 0.0;
}

void GPSCallback(const gps_common::GPSFix::ConstPtr& msg)
{
    g_latest_lon = msg->longitude;
    g_latest_lat = msg->latitude;
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "listener");
    ros::NodeHandle n;
    ros::Subscriber sub = n.subscribe("/GPSFix", 10, GPSCallback);
    ros::Timer timer = n.createTimer(ros::Duration(0.1), timerCallback);

    ros::spin();

    return 0;
}

You could do this several ways. Quick and dirty is to combine the GPS message callback and a Timer. Below you see that a timer is created that gets called at 10 Hz and uses the latest GPS data. It then resets the stored GPS data back to zeros until a new GPS message arrives. This will always print out zeros unless you have fresh GPS data.

Note that global variables are used here, but the link to the Timers page has examples of how to use a callback function for a Timer that is part of a class. Then, you could store the latest GPS data as class member variables.

As an aside, you rarely ever want to call sleep() inside a callback function. I'm pretty sure that this will cause that thread to stop running and you will get unexpected results, most likely dropping a lot of messages as your queue fills up.

#include <ros/ros.h>
#include <ros/time.h>
#include <gps_common/GPSFix.h>

using namespace std;

double g_latest_lat = 0.0;
double g_latest_lon = 0.0;

void timerCallback(const ros::TimerEvent& event)
{
    ROS_INFO("(lat, lon) = (%lf, %lf)", g_latest_lat, g_latest_lon);
    g_latest_lat = 0.0;
    g_latest_lon = 0.0;
}

void GPSCallback(const gps_common::GPSFix::ConstPtr& msg)
{
    g_latest_lon = msg->longitude;
    g_latest_lat = msg->latitude;
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "listener");
    ros::NodeHandle n;
    ros::Subscriber sub = n.subscribe("/GPSFix", 10, GPSCallback);
    ros::Timer timer = n.createTimer(ros::Duration(0.1), timerCallback);

    ros::spin();

    return 0;
}

You could do this several ways. Quick and dirty is to combine the GPS message callback and a Timer. Below you see that a timer is created that gets called at 10 Hz and uses the latest GPS data. It then resets the stored GPS data back to zeros until a new GPS message arrives. This will always print out zeros unless you have fresh GPS data.

Note that global variables are used here, but the link to the Timers page has examples of how to use a callback function for a Timer that is part of a class. Then, you could store the latest GPS data as class member variables.

As an aside, you rarely ever want to call sleep() inside a callback function. I'm pretty sure that this will cause that thread to stop running and you will get unexpected results, most likely dropping a lot of messages as your queue fills up.

#include <ros/ros.h>
#include <ros/time.h>
#include <gps_common/GPSFix.h>

using namespace std;

double g_latest_lat = 0.0;
double g_latest_lon = 0.0;

void timerCallback(const ros::TimerEvent& event)
{
    ROS_INFO("(lat, lon) = (%lf, %lf)", g_latest_lat, g_latest_lon);
    g_latest_lat = 0.0;
    g_latest_lon = 0.0;
}

void GPSCallback(const gps_common::GPSFix::ConstPtr& msg)
{
    g_latest_lon = msg->longitude;
    g_latest_lat = msg->latitude;
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "listener");
    ros::NodeHandle n;
    ros::Subscriber sub = n.subscribe("/GPSFix", 10, GPSCallback);
    ros::Timer timer = n.createTimer(ros::Duration(0.1), timerCallback);

    ros::spin();

    return 0;
}

You could do this several ways. Quick and dirty is to combine the GPS message callback and a Timer. Below you see that a timer is created that gets called at 10 Hz and uses the latest GPS data. It then resets the stored GPS data back to zeros until a new GPS message arrives. This will always print out zeros unless you have fresh GPS data.

Note that global variables are used here, but the link to the Timers page has examples of how to use a callback function for a Timer that is part of a class. Then, you could store the latest GPS data as class member variables.

As an aside, you rarely ever want to call sleep() inside a callback function. I'm pretty sure that this will cause that thread to stop running and you will get unexpected results, most likely dropping a lot of messages as your queue fills up.

EDIT For the updated question you could keep track of whether you recently received a GPS message. In the timer callback you always print zero, and based on whether you have new GPS data you would print that as well.

#include <ros/ros.h>
#include <ros/time.h>
#include <gps_common/GPSFix.h>

double g_latest_lat = 0.0;
double g_latest_lon = 0.0;
bool g_have_fresh_gps_data = false;

void timerCallback(const ros::TimerEvent& event)
{
    ROS_INFO("(lat, lon) = (%lf, %lf)", g_latest_lat, g_latest_lon);
printf("0\n");
    if (g_have_fresh_gps_data)
    {
        printf("Longitude: %lf\nLatitude: %lf\n\n", g_latest_lon, g_latest_lat);
    }
    g_latest_lat = 0.0;
    g_latest_lon = 0.0;
    g_have_fresh_gps_data = false;
}

void GPSCallback(const gps_common::GPSFix::ConstPtr& msg)
{
    g_latest_lon = msg->longitude;
    g_latest_lat = msg->latitude;
    g_have_fresh_gps_data = true;
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "listener");
    ros::NodeHandle n;
    ros::Subscriber sub = n.subscribe("/GPSFix", 10, GPSCallback);
    ros::Timer timer = n.createTimer(ros::Duration(0.1), timerCallback);

    ros::spin();

    return 0;
}