关于GPSD;
GPSD是一个Linux下的一个守护进程,用以侦听来自GPS接收器的位置等信息,并将这些位置信息转换成一种简化的格式。
GPSD支持二十多种不同GPS输出格式的GPS接收机,例如NMEA、Ashtech、AIVDM、iTalk Binary、Trimble TSIP、RTCM、uBlox UBX binary等。将收到的packet解析之后,可以通过D-BUS、共享内存和socket(默认端口为:2947)方式输出。
GPSD packet中同时提供了多种客户端,例如gpsctl、gpsmon、gpspipe等,可以根据需要进行使用。
gpsd is a userland daemon acting as a translator between GPS and AIS receivers and their clients. gpsd listens on port 2947 for clients requesting position/time/velocity information. The receivers are expected to generate position information in a well-known format -- as NMEA-0183 sentences, SiRF binary, Rockwell binary, Garmin binary
format, or other vendor binary protocols. gpsd takes this information from the GPS and translates it into something uniform and easier to understand for clients. The distribution includes sample clients, application interface libraries, and test/profiling tools.
There is a website for GPSD where you can find updates, news, and project mailing lists; look for that URL in the scons recipe, the file SConstruct in this top-level directory. See that website for a list of GPS units known to be compatible.
See the file INSTALL for installation instructions and some tips on how to troubleshoot your installation. The file build.txt has instructions for building from source. The packaging/ directory contains resources and suggestions for packagers and distribution integrators.
以下重点介绍libgps 函数的使用:
typedef enum {
GNSS_FIX_STATUS_NO, /**< GNSS has no fix, i.e. position, velocity, time cannot be determined */
GNSS_FIX_STATUS_TIME, /**< GNSS can only determine the time, but not position and velocity */
GNSS_FIX_STATUS_2D, /**< GNSS has a 2D fix, i.e. the horizontal position can be determined but not the altitude.
This implies that also velocity and time are available. */
GNSS_FIX_STATUS_3D /**< GNSS has a 3D fix, i.e. position can be determined including the altitude.
This implies that also velocity and time are available. */
} EGNSSFixStatus;
typedef struct {
uint64_t timestamp; /**< Timestamp of the acquisition of the UTC date/time [ms].
All sensor/GNSS timestamps must be based on the same time source. */
uint16_t year; /**< Year fraction of the UTC time. Unit: [year] Number equivalent to the year (4 digits) */
uint8_t month; /**< Month fraction of the UTC time. Unit: [month] Number betweeen 0 and 11 */
uint8_t day; /**< Day of month fraction of the UTC time. Unit: [day]. Number between 1 and 31 */
uint8_t hour; /**< Hour fraction of the UTC time. Unit: [hour] Number between 0 and 23 */
uint8_t minute; /**< Minute fraction of the UTC time. Unit: [minutes] Number between 0 and 59 */
uint8_t second; /**< Second fraction of the UTC time. Unit: [seconds] Number between 0 and 59.
In case of a leap second this value is 60. */
uint16_t ms; /**< Millisecond fraction of the UTC time. Unit: [milliseconds] Number between 0 and 999 */
int8_t leapSeconds; /**< Number of leap seconds, i.e. difference between GPS time and UTC. Unit: [seconds].
Note: value before 01-July-2015: 16; from 01-July-2015: 17; further changes possible. */
uint32_t validityBits; /**< Bit mask indicating the validity of each corresponding value.
[bitwise or'ed @ref EGNSSTimeValidityBits values].
Must be checked before usage. */
} SDateTime;
typedef struct {
uint64_t timestamp; /**< Timestamp of the acquisition of the GNSS data [ms].
All sensor/GNSS timestamps must be based on the same time source. */
//position
double latitude; /**< Latitude in WGS84 in [degree]. */
double longitude; /**< Longitude in WGS84 in [degree]. */
float altitudeMSL; /**< Altitude above mean sea level (geoid) in [m]. */
float altitudeEll; /**< Altitude above WGS84 ellipsoid in [m]. */
//velocity
float hSpeed; /**< Horizontal speed [m/s]. */
float vSpeed; /**< Vertical speed [m/s]. */
float heading; /**< GNSS course angle [degree] (0 => north, 90 => east, 180 => south, 270 => west, no negative values). */
//quality parameters: satellite constellation
float pdop; /**< The positional (3D) dilution of precision. [Note: pdop^2 = hdop^2+vdop^2] */
float hdop; /**< The horizontal (2D) dilution of precision. */
float vdop; /**< The vertical (altitude) dilution of precision. */
uint16_t usedSatellites; /**< Number of satellites used for the GNSS fix. */
uint16_t trackedSatellites; /**< Number of satellites from which a signal is received. */
uint16_t visibleSatellites; /**< Number of satellites expected to be receivable, i.e. above horizon or elevation mask. */
//quality parameters: error estimates
float sigmaHPosition; /**< Standard error estimate of the horizontal position in [m]. */
float sigmaAltitude; /**< Standard error estimate of altitude in [m]. */
float sigmaHSpeed; /**< Standard error estimate of horizontal speed in [m/s]. */
float sigmaVSpeed; /**< Standard error estimate of vertical speed in [m/s]. */
float sigmaHeading; /**< Standard error estimate of horizontal heading/course in [degree]. */
//quality parameters: overall GNSS fix status
EGNSSFixStatus fixStatus; /**< Value representing the GNSS mode. */
uint32_t fixTypeBits; /**< Bit mask indicating the sources actually used for the GNSS calculation.
[bitwise or'ed @ref EGNSSFixType values]. */
//gnss system information
uint32_t activatedSystems; /**< Bit mask indicating the satellite systems that are activated for use
[bitwise or'ed @ref EGNSSSystem values].*/
uint32_t usedSystems; /**< Bit mask indicating the satellite systems that are actually used for the position fix
[bitwise or'ed @ref EGNSSSystem values].*/
//validity bits
uint32_t validityBits; /**< Bit mask indicating the validity of each corresponding value.
[bitwise or'ed @ref EGNSSPositionValidityBits values].
Must be checked before usage. */
} SGNSSPosition;
bool phraseTime(struct gps_data_t* pGpsData, SDateTime* pDateTime)
{
static timestamp_t oldTime = 0;
if(!pGpsData || !pDateTime)
{
return false;
}
if ((pGpsData->set & TIME_SET) && (oldTime != pGpsData->fix.time))
{
char month [12] [4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
pDateTime->validityBits = 0;
pDateTime->timestamp = pGpsData->fix.time;
if(pGpsData->set & TIME_SET)
{
oldTime = pGpsData->fix.time;
time_t unix_sec = pGpsData->fix.time;
struct tm * ptm = gmtime (&unix_sec);
pDateTime->year = ptm->tm_year+1900;
pDateTime->month = ptm->tm_mon;
pDateTime->day = ptm->tm_mday;
pDateTime->hour = ptm->tm_hour;
pDateTime->minute = ptm->tm_min;
pDateTime->second = ptm->tm_sec;
pDateTime->ms = 1000*fmod(pGpsData->fix.time, 1.0);
d_printf(D_DEBUG, NULL, "UTC: d-%s-d d:d:d\n", pDateTime->year, month[pDateTime->month], pDateTime->day, pDateTime->hour, pDateTime->minute, pDateTime->second);
}
}
return true;
}
bool phrasePos(struct gps_data_t* pGpsData, SGNSSPosition* pPosition)
{
static float oldHSpeed = 0;
static float oldVSpeed = 0;
static float oldHeading = 0;
static uint16_t oldUsedSatellites = 0;
static uint16_t oldVisibleSatellites = 0;
bool positionAvailable = false;
bool velocityAvailable = false;
bool fixStatusChanged = false;
bool satellitesChanged = false;
if(!pGpsData || !pPosition)
{
return false;
}
pPosition->validityBits = 0;
pPosition->timestamp = pGpsData->fix.time;
if( ((pGpsData->set & LATLON_SET) || (pGpsData->set & ALTITUDE_SET)) &&
(pGpsData->set & MODE_SET) &&
((pGpsData->fix.mode == MODE_2D) || (pGpsData->fix.mode == MODE_3D)) )
{
positionAvailable = true;
if(pGpsData->set & LATLON_SET)
{
pPosition->latitude = pGpsData->fix.latitude;
pPosition->longitude = pGpsData->fix.longitude;
d_printf(D_DEBUG, NULL, "Latitude: %lf\n", pPosition->latitude);
d_printf(D_DEBUG, NULL, "Longitude: %lf\n", pPosition->longitude);
}
if((pGpsData->set & ALTITUDE_SET) && (pGpsData->fix.mode == MODE_3D))
{
pPosition->altitudeMSL = (float)pGpsData->fix.altitude;
d_printf(D_DEBUG, NULL, "Altitude: %lf\n", pPosition->altitudeMSL);
}
}
if( ((pGpsData->set & SPEED_SET) && (oldHSpeed != (float)pGpsData->fix.speed)) ||
((pGpsData->set & CLIMB_SET) && (oldVSpeed != (float)pGpsData->fix.climb)) ||
((pGpsData->set & TRACK_SET) && (oldHeading != (float)pGpsData->fix.track)) )
{
velocityAvailable = true;
if(pGpsData->set & SPEED_SET)
{
oldHSpeed = pPosition->hSpeed;
pPosition->hSpeed = (float)pGpsData->fix.speed;
d_printf(D_DEBUG, NULL, "Speed: %lf\n", pPosition->hSpeed);
}
if(pGpsData->set & CLIMB_SET)
{
oldVSpeed = pPosition->vSpeed;
pPosition->vSpeed = (float)pGpsData->fix.climb;
d_printf(D_DEBUG, NULL, "Climb: %lf\n", pPosition->vSpeed);
}
if(pGpsData->set & TRACK_SET)
{
oldHeading = pPosition->heading;
pPosition->heading = (float)pGpsData->fix.track;
d_printf(D_DEBUG, NULL, "Heading: %lf\n", pPosition->heading);
}
}
satellitesChanged = ((oldUsedSatellites != (uint16_t)pGpsData->satellites_used) ||
(oldVisibleSatellites != (uint16_t)pGpsData->satellites_visible));
if(((pGpsData->set & MODE_SET) && fixStatusChanged) ||
(pGpsData->set & DOP_SET) ||
((pGpsData->set & SATELLITE_SET) && satellitesChanged))
{
//pPosition->fixStatus = convertToFixStatus(pGpsData->fix.mode);
d_printf(D_DEBUG, NULL, "FixStatus: %d\n", (int)pPosition->fixStatus);
pPosition->pdop = (float)pGpsData->dop.pdop;
d_printf(D_DEBUG, NULL, "pdop: %lf\n", pPosition->pdop);
pPosition->hdop = (float)pGpsData->dop.hdop;
d_printf(D_DEBUG, NULL, "hdop: %lf\n", pPosition->hdop);
pPosition->vdop = (float)pGpsData->dop.vdop;
d_printf(D_DEBUG, NULL, "vdop: %lf\n", pPosition->vdop);
pPosition->sigmaHPosition = (float)pGpsData->fix.epx;
d_printf(D_DEBUG, NULL, "sigmaHorPosition: %lf\n", pPosition->sigmaHPosition);
pPosition->sigmaHSpeed = (float)pGpsData->fix.eps;
d_printf(D_DEBUG, NULL, "sigmaHorSpeed: %lf\n", pPosition->sigmaHSpeed);
pPosition->sigmaHeading = (float)pGpsData->fix.epd;
d_printf(D_DEBUG, NULL, "sigmaHeading: %lf\n", pPosition->sigmaHeading);
if(pGpsData->satellites_used >= 0)
{
oldUsedSatellites = pPosition->usedSatellites;
pPosition->usedSatellites = (uint16_t)pGpsData->satellites_used;
d_printf(D_DEBUG, NULL, "Used Satellites: %d\n", pPosition->usedSatellites);
}
if(pGpsData->satellites_visible >= 0)
{
oldVisibleSatellites = pPosition->visibleSatellites;
pPosition->visibleSatellites = (uint16_t)pGpsData->satellites_visible;
d_printf(D_DEBUG, NULL, "Visible Satellites: %d\n", pPosition->visibleSatellites);
}
}
d_printf(D_DEBUG, NULL, "gps: mode %d, time 000000, lat %f, lon %f, alt %f, head %f, speed %f\n",
pPosition->fixStatus,
pPosition->latitude,
pPosition->longitude,
pPosition->altitudeMSL,
pPosition->heading,
pPosition->hSpeed);
return true;
}
static void testGpslibusage(void)
{
char* device = 0;
struct gps_data_t gpsdata;
unsigned int flag = WATCH_ENABLE;
device = getenv("GNSS_DEVICE");
if(<strong>gps_open</strong>("localhost", "2947", &gpsdata) != 0)
{
d_printf(D_DEBUG, NULL, "no gpsd running or network error: %d, %s",errno, gps_errstr(errno));
exit(EXIT_FAILURE);
}
flag |= WATCH_JSON;
if(device != 0)
{
flag |= WATCH_DEVICE;
d_printf(D_DEBUG, NULL, "device: %s",device);
}
(void)<strong>gps_stream</strong>(&gpsdata, flag, device);
int counter = 0;
while (1)
{
if(!<strong>gps_waiting</strong>(&gpsdata, 15000000))
{
d_printf(D_DEBUG, NULL, "error while waiting");
}
else
{
if(<strong>gps_read</strong>(&gpsdata))
{
SDateTime datetime = { 0 };
if(!phraseTime(&gpsdata,&datetime))
{
d_printf(D_DEBUG, NULL, "error extracting Time");
}
SGNSSPosition position = { 0 };
if(!phrasePos(&gpsdata,&position))
{
d_printf(D_DEBUG, NULL, "error extracting position data");
}
}
}
counter++;
if(counter == 5) break;
}
(void)<strong>gps_close</strong>(&gpsdata);
return;
}
搞个main函数调用即可;
转载请注明原文地址: https://ju.6miu.com/read-1125921.html