[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Sending commands to device while gpsd is running
From: |
Filip Kubicz |
Subject: |
Re: Sending commands to device while gpsd is running |
Date: |
Wed, 13 Apr 2022 10:41:14 +0200 |
User-agent: |
Zoho Mail |
Hi!
I have found that gps_send() format should follow the command for from gpsd(8)
page.
https://gpsd.gitlab.io/gpsd/libgps.html#_description
https://gpsd.gitlab.io/gpsd/gpsd.html#_gps_device_management
"To send a control string to a specified device, write to the control socket a
'!', followed by the device name, followed by '=', followed by the control
string."
So I added the '!<device_name>=' to the beginning of the command:
// '!<device_name>=', added to request gpsd to send the control string to the
device
int msg_len = snprintf(message, MSG_MAX_LEN, "!/dev/ttyGPS0=%s*%02X\r\n",
payload, pqtm_checksum(payload, payload_len));
int n = gps_send(&gpsd_data, message);
However there is still no response:
gpsd:CLIENT: <= client(0): !/dev/ttyGPS0=$PQTMVEHMSG,2,0,0,1*3D\x0d\x0a
gpsd:CLIENT: => client(0): =
Also tried with "gpsd -D 2 -N -n /dev/ttyGPS0"
Previously I placed the -n option incorrectly after the device name.
Thanks,
Filip Kubicz
filip@kubicz.engineer
tel. (+48) 697 088 078
---- On Wed, 13 Apr 2022 10:12:04 +0200 Filip Kubicz <filip@kubicz.engineer>
wrote ----
> Hi Gary!
>
> > IF you have a raw capture with some $PQTMINS then send it here. That
> > can be used for a regression test and to validate its decode.
>
> I'm attaching a raw capture file so it can be added to the regression test:
> https://paste.ee/p/uY1oT
> It contains the $PQTMINS in it's full lifecycle, from not calibrated to
> calibrated algorithm state.
>
> I'm now once again trying to implement feeding the GNSS device with wheel
> data.
> Feeding the wheel tick with UART directly works, and the module responds
> with $PQTMVEHMSG to my every write - visible in the captured file.
>
> However, I want to do it via gpsd to let it be the only program using the
> serial port.
> I added the -n option as you mentioned previously.
>
> My app:
> Apr 12 17:11:36 gps_send: $PQTMVEHMSG,2,0,0,1*19\r\n
> Apr 12 17:11:36 gps_send: $PQTMVEHMSG,2,0,0,1*19\r\n
>
> gpsd with debug enabled:
> # gpsd -D 2 -N /dev/ttyGPS0 -n
> gpsd:WARN: This system has a 32-bit time_t. This gpsd will fail at
> 2038-01-19T03:14:07Z.
> gpsd:WARN: KPPS:/dev/ttyGPS0 no HAVE_SYS_TIMEPPS_H, PPS accuracy will suffer
> gpsd:WARN: NMEA0183: can't use GNS time until after ZDA or RMC has supplied
> a year.
> gpsd:WARN: NMEA0183: can't use GNS time until after ZDA or RMC has supplied
> a year.
>
> gpsd:CLIENT: => client(0):
> {"class":"VERSION","release":"3.23.1","rev":"3.23.1","proto_major":3,"proto_minor":14}\x0d\x0a
>
> gpsd:CLIENT: <= client(0): $PQTMVEHMSG,2,0,0,1*19\x0d\x0a
> gpsd:CLIENT: => client(0): =
> gpsd:CLIENT: <= client(0): $PQTMVEHMSG,2,0,0,1*19\x0d\x0a
> gpsd:CLIENT: => client(0): =
>
> Unfortunately, gps_send() from gps.h does not send the packets to the GNSS,
> or incorrect message is sent out and there is no response.
>
> Code:
> int wheel_tick_gpsd_connect(void)
> {
> if (0 != gps_open("localhost", "2947", &gps_data)) {
> write_syslog_err("gpsd connect error\n");
> return WHEEL_TICK_CONNECT_ERROR;
> }
> return 0;
> }
>
> void wheel_tick_feed(const uint32_t wheel_tick_count)
> {
> char payload[PAYLOAD_MAX_LEN];
> char message[MSG_MAX_LEN];
>
> // Construct the payload for checksum calculation.
> int payload_len = snprintf(payload, PAYLOAD_MAX_LEN,
> "$PQTMVEHMSG,2,0,%d,1", wheel_tick_count);
> // Construct full message with checksum.
> int msg_len = snprintf(message, MSG_MAX_LEN, "$%s*%02X\r\n", payload,
> pqtm_checksum(payload, payload_len));
>
> // gps_send accepts a null-terminated string.
> int n = gps_send(&gps_data, message);
> if (n < 0) {
> write_syslog_err("wheel tick write failed, n=%d\n", n);
> }
> }
>
> wheel_tick_gpsd_connect() is called once, wheel_tick_feed is called in a
> loop.
> gps_open() and gps_send() both return 0.
> Confirmed that the constructed payload and message are what the module
> expects - it works when sent over UART or via gpsctl -x.
> For sending, do I need to set up a stream with gps_stream()? Tried that as
> well but the behavior is similar. Or maybe there is some other part missing?
>
> > gps.send() in Python is not gps_send() in C. Different animals.
> I can see the Python usage in ubxtool, but right now I'm using C and would
> need a C API example.
>
> I've done a comparison with gpsctl -x. Command sent without checksum, as
> specifed in the gpsctl docs, is received by the device, which responds
> correctly. Working command:
> gpsctl -x '$PQTMVEHMSG,2,0,0,1' -D 3 /dev/ttyGPS0
> But before that, gpsctl -x reinitialized the device.
> Also, there is no "gpsd:CLIENT: <= " in the gpsd daemon log, which means
> gpsctl -x is not meant to be used when a gpsd daemon is running (as it
> forces the "low-level access").
> # gpsctl -x '$PQTMVEHMSG,2,0,0,1*19' -D 3
> gpsctl:ERROR: device must be specified for low-level access.
>
> Looking at the gpsctl, I tried to put a payload without the NMEA checksum to
> gps_send(), but it didn't work either, gps_send() does not add the checksum.
> So it must be some other issue.
> gpsd:CLIENT: <= client(0): $PQTMVEHMSG,2,0,0,1\x0a
> gpsd:CLIENT: => client(0): =
>
> Please advise how to properly do the send ;)
>
> Kind regards,
> Filip
>
> filip@kubicz.engineer
> tel. (+48) 697 088 078
>
>
> >
> > ---- On Thu, 30 Dec 2021 23:46:44 +0100 Gary E. Miller <gem@rellim.com>
> wrote ----
> >
> > > Yo Filip!
> > >
> > > I'm replying to the list. I only take offlist email from paying
> > > clients.
> > > On Thu, 30 Dec 2021 23:28:14 +0100
> > > Filip Kubicz <filip@kubicz.engineer> wrote:
> > >
> > > > > You are skipping a lot of details. What version gpsd? How are
> > > > > you starting gpsd? Are you using the "-n" option? Was gpsd
> > > > > running when you did the below?
> > > > >
> > > >
> > > > gpsd 3.21. I understand that I should update to 3.23.1 whenever
> > > > possible.
> > >
> > > Yup. A lot of "Quectel Querks" fixed in the newer version.
> > >
> > > > You are right, there is no -n option. I'll add it to allow gpsd to
> > > > get the data before the client connects.
> > >
> > > It does a lot more than that. Just do it.
> > >
> > > > In the above situation, both
> > > > gpsd and client are running. Command in this case is
> > > > "$PQTMCFGEINSMSG,1,1,0,0,10*3F\r\n". Which may not be correct NMEA,
> > > > but it's only for the receiver. Not for gpsd to worry about.
> > >
> > > Yes, but gpsd has to worry about the response. Not sure what gpsd
> > > would do with $COMMANDACKOK.
> > >
> > > > > > When I just send the command over UART, the command succeeds
> and
> > > > > > the device sends back $COMMANDACKOK*16
> > > > >
> > > > > Which, of course, is invalid NMEA... We can deal with that
> > > > > "querk" later.
> > > > >
> > > >
> > > > In this case it doesn't matter if this is valid NMEA, because gpsd
> > > > doesn't need to parse it.
> > >
> > > Yes, and no. If it confuses the packetizer, then there will be
> problems.
> > >
> > > > Best case would be to let the client
> > > > program receive it. But probably it's not that simple, as gpsd would
> > > > have to know that it should just pass certain commands, and parse
> all
> > > > the other usual NMEA sentences.
> > >
> > > gpsd passes back all receiver NMEA already. Not sure if that is
> > > detected as NMEA.
> > >
> > > > > > What would be the best way to send a command to a device while
> > > > > > gpsd is running?
> > > > >
> > > > > Besst depends a lot on what language you prefer. gpsctl works,
> or
> > > > > you can code up a bit of Python, C, etc. The protocol is simple.
> > > > >
> > > >
> > > > I have a Python client, which does session.stream(gps.WATCH_ENABLE |
> > > > gps.WATCH_NEWSTYLE) and then session.next(). From what you say I
> > > > guess you mean using gps.send()? Isn't it "Deprecated and unstable"
> > > > according to https://gpsd.gitlab.io/gpsd/client-howto.html ?
> > >
> > > gps.send() in Python is not gps_send() in C. Different animals.
> > >
> > >
> > > > I don't want to do any of the magic that gpsctl performs here:
> > > > gpsctl:PROG: switching to match packet type 1:
> > > > $GNRMC,105549.43,V,,,,,,,301221,,,N,V*11\x0d\x0a [...]
> > > > gpsctl:PROG: => Probing for Garmin NMEA
> > >
> > > Nor will you have to, once "-n" is working. That is not even gpsctl,
> that
> > > is from libgps.
> > >
> > > > I only want to shuttle a command to the receiver over UART, without
> > > > competing with gpsd for the serial port access. I can use python API
> > > > or command line.
> > >
> > > If you look at ubxtool, it does a lot of gps.send(). Pretty easy
> > > once you have the boilerplate set. or gpsctl.
> > >
> > > > > > The commands are NMEA-like text. The commands are
> > > > > > independent from the daemon operation.
> > > > >
> > > > > Yeah. "NMEA like". Just enough like NMEA to confuse things. A
> > > > > lot.
> > > >
> > > > That's another story, that I will add support in gpsd for parsing
> > > > position from $PQTMINS message. But let's leave it for now and take
> > > > care of the commands first.
> > >
> > > If you do that, send it here, and I'll add it to
> drivers/driver_nmea0183.c
> > > Another "Quectel Querk". You will find many more of those...
> > >
> > > IF you have a raw capture with some $PQTMINS then send it here. That
> > > can be used for a regression test and to validate its decode.
> > >
> > > RGDS
> > > GARY
> > >
> ---------------------------------------------------------------------------
> > > Gary E. Miller Rellim 109 NW Wilmington Ave., Suite E, Bend, OR 97703
> > > gem@rellim.com Tel:+1 541 382 8588
> > >
> > > Veritas liberabit vos. -- Quid est veritas?
> > > "If you can't measure it, you can't improve it." - Lord Kelvin
> > >
> >
>
>
>
Re: Sending commands to device while gpsd is running, Gary E. Miller, 2022/04/13