This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm whether you accept or reject these cookies being set.

A cookie will be stored in your browser regardless of choice to prevent you being asked this question again. You will be able to change your cookie settings at any time using the link in the footer.

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Garmin plotter crashes nmea communication
#1
Hi Sean,

 
I'm just starting a new topic as there is no reaction on the original topic (only compass mode) and that topic is just the result of this problem.
 
I have a Garmin Plotter (so does Webber83) it sends the GPAPB sentence (I think other plotters do this aswell). If there is no active waypoint the sentence is still transmitted but with empty data.
 
When i send my nmea data from openplotter 1.2 to the TinyPilot (tpc port 20220) everything works fine as long as there is an active waypoint. As soon as i remove the active waypoint on the plotter communication with Tinypilot crashes.
 
in your code (nmea.py) you do (2x line 485 and 486) a float without checking for empty data (or try, except) which causes the script to crash when the data is an empty string, communication stops, Tinypilot doesn't get gps or wind data and only displays compass mode.
 
I am also curious why in nmea.py the mode is switched to compass (line 481) as soon as it sees an APB sentence with a magnetic heading. 
 
I do set waypoints in my plotter and sometimes like the autopilot to steer on the wind direction for instance when i have to tack against the wind. If the autopilot then switches from wind to compass it would try to head to the waypoint and steer the boat straight against the wind. To my opinion it would be good if the autopilot would only try to steer to the waypoint when it is on gps mode and keep it on gps mode and if it is on wind steering just ignore the APB sentence.

if i'm wrong please also let me know.



greetings Rob
Reply
#2
(2019-08-06, 11:33 PM)rmvdmrl Wrote: Hi Sean,

 
I'm just starting a new topic as there is no reaction on the original topic (only compass mode) and that topic is just the result of this problem.
 
I have a Garmin Plotter (so does Webber83) it sends the GPAPB sentence (I think other plotters do this aswell). If there is no active waypoint the sentence is still transmitted but with empty data.
 
When i send my nmea data from openplotter 1.2 to the TinyPilot (tpc port 20220) everything works fine as long as there is an active waypoint. As soon as i remove the active waypoint on the plotter communication with Tinypilot crashes.
 
in your code (nmea.py) you do (2x line 485 and 486) a float without checking for empty data (or try, except) which causes the script to crash when the data is an empty string, communication stops, Tinypilot doesn't get gps or wind data and only displays compass mode.
 
I am also curious why in nmea.py the mode is switched to compass (line 481) as soon as it sees an APB sentence with a magnetic heading. 
 
You must have an older pypilot version. Did you update from git? I believe the crash has been fixed.

As for changing to compass mode if apb has magnetic heading.. what should it do instead?
Quote:I do set waypoints in my plotter and sometimes like the autopilot to steer on the wind direction for instance when i have to tack against the wind. If the autopilot then switches from wind to compass it would try to head to the waypoint and steer the boat straight against the wind. To my opinion it would be good if the autopilot would only try to steer to the waypoint when it is on gps mode and keep it on gps mode and if it is on wind steering just ignore the APB sentence.

This is a personal preference then. It's possible for route following to work for both gps and compass modes as you have found. Can't you just output apb sentence with gps (true north) heading?

It currently switches to gps or compass mode if apb sentence is received making steering to wind impossible unless you deactivate the route or waypoint. This is convenient since you don't have to switch modes. If the gps drops out, it automatically falls back to compass holding course and will switch back to gps and resume following the route when gps is available again.

What you suggest would prevent this, but it could be convenient as well. I'm not sure it's better. It would be very easily to implement this feature in the autopilot route plugin of opencpn. The plugin would simply not output apb messages if the autopilot is not in gps mode if this option is set. I can't make it work for other chart plotters than opencpn unless pypilot itself is changed and it would need this extra option.

What do you think?
Reply
#3
Hi Sean, thanks for your reply,

I'm afraid the issue is not solved with the latest version on Git, the Nmea.py is still missing the check for empty string.

I see what you mean by the gps/compass mode there is however no way in my garmin that lets me config the APB sentence and it would not solve the fact that i can't have waypoints active while tacking that let's me see where i have to end up en the distance to the waypoint/route.

I might be a bit biased but of course i think my option is more convenient as you can set the modes on Tinypilot and in openCPN. so this only takes a few seconds while you could be tacking for hours or days and keep the autopilot at wind mode instead of removing the waypoint, having no idea where to end up or how far you have to go.

I'm not sure but i thought OpenCPN outputs APAPB instead of GPAPB (i think most standard plotters use GPAPB), would it be an option to make a difference between those two, and get both options for example like (well something like this it might contain errors as i'm not sure of a couple of things and i am not exactly a python programmer):

    if line[1:6] == 'APAPB' and time.time() - self.last_apb_time > 1:
            self.last_apb_time = time.time()
            data = line[7:len(line)-3].split(',')
            if self.last_values['ap.enabled']:
                mode = 'compass' if data[13] == 'M' else 'gps'
                if self.last_values['ap.mode'] != mode:
                    self.client.set('ap.mode', mode)
#try  (some check should be here but didn't wan't to chance much to this piece as you will have a beter vision about this)
            command = float(data[12])
            xte = float(data[2])
            xte = min(xte, 0.15) # maximum 0.15 miles
            if data[3] == 'L':
                xte = -xte
            command += 300*xte; # 30 degrees for 1/10th mile
            if abs(self.last_values['ap.heading_command'] - command) > .1:
                self.client.set('ap.heading_command', command)
#except
            return True
        elif line[1:6] == 'GPAPB' and time.time() - self.last_apb_time > 1:
            self.last_apb_time = time.time()
            data = line[7:len(line)-3].split(',')
            if self.last_values['ap.enabled'] and self.last_values['ap.mode'] == 'gps':
               try: 
                  command = float(data[12])
                  xte = float(data[2])
                  xte = min(xte, 0.15) # maximum 0.15 miles
                  if data[3] == 'L':
                      xte = -xte
                  command += 300*xte; # 30 degrees for 1/10th mile
                  if abs(self.last_values['ap.heading_command'] - command) > .1:
                      self.client.set('ap.heading_command', command)
                  return True
               except: return False 
        return False

Well it's just an idea hope you can do something with this.

Greetings Rob
Reply
#4
So if the chart plotter sends the message GPAPB, then pypilot should not switch modes, and it should only change the course if it is in the correct mode.

Otherwise **APB will change to the needed mode? Would this work for you? I think it's acceptable for now.
Reply
#5
(2019-08-08, 07:57 PM)seandepagnier Wrote: So if the  chart plotter sends the message  GPAPB, then pypilot should  not switch modes, and  it should only change the course if  it is in the correct mode.

Otherwise **APB will change to the  needed mode?     Would this work for you?   I  think it's acceptable for now.

Hi Sean,

That is indeed what what i was thinking. I think this would be great for now, it keeps both functionality. Do you think checking each GPAPB line (mostly empty) would be an issue (performance) or would it be better to only proces and check the GPAPB if it is longer than an empty GPAPB (and or **APB)?, Perhaps with a future update if possible it may be nice to have an extra mode "Waypoint" or "Route" steering" combined with audio alarm (beeper on one of the gpio pins) and confirmation on course changes for arival and heading to the next waypoint.

Greetings and thanks for looking into this, Rob
Reply
#6
Hi Sean,

I modified nmea.py with this:

if line[1:6] == 'APAPB' and time.time() - self.last_apb_time > 1:
            self.last_apb_time = time.time()
            data = line[7:len(line)-3].split(',')
            if self.last_values['ap.enabled']:
                mode = 'compass' if data[13] == 'M' else 'gps'
                if self.last_values['ap.mode'] != mode:
                    self.client.set('ap.mode', mode)
            try:
               command = float(data[12])
               xte = float(data[2])
               xte = min(xte, 0.15) # maximum 0.15 miles
               if data[3] == 'L':
                   xte = -xte
               command += 300*xte; # 30 degrees for 1/10th mile
               if abs(self.last_values['ap.heading_command'] - command) > .1:
                   self.client.set('ap.heading_command', command)
            except: return False
            return True
        elif line[1:6] == 'GPAPB' and time.time() - self.last_apb_time > 1:
            self.last_apb_time = time.time()
            data = line[7:len(line)-3].split(',')
            if self.last_values['ap.enabled'] and self.last_values['ap.mode'] == 'gps':
               try: 
                  command = float(data[12])
                  xte = float(data[2])
                  xte = min(xte, 0.15) # maximum 0.15 miles
                  if data[3] == 'L':
                      xte = -xte
                  command += 300*xte; # 30 degrees for 1/10th mile
                  if abs(self.last_values['ap.heading_command'] - command) > .1:
                      self.client.set('ap.heading_command', command)
                  return True
               except: return False 
        return False

tested it and nmea communication doesn't crash anymore. i can select other modes when i have an active waypoint so it seems to work. I just haven't done actual navigating to a waypoint as the wheather is not good today. It is stil a bit unclear to me what would be the easyest/correct procedure to get it in the squashed filesystem but eventualy i got it in there.

Greetings Rob
Reply
#7
The way to get it updated after modifying is:

$ . pypilot.build

In any case, it's best to submit code changes with a pull request on github. This makes tracking changes much easier.

I don't think there is any issue of cpu usage for this test. It should do the normal behavior for any APB not just APAPB.
Reply
#8
Trying to solve the issue on my tinypilot I followed instructions available on pypilot wiki to get last version but had some further problem:
-I had to replace https:// in the url with git:// to manage to download the code
-building it I found what seems to be an error in servo.py line 600. I am not a big expert in Python but I think the ‘&&’ is the problem: removing one of two the error disappears.
-after updating communication still crashes if no waypoint is set in Garmin Plotter 
-I am not sure if update is persistent on tinypilot (due to tinycore linux),
Did not understwnd which is the directory with actual installation to check if scripts are updated,
and I am not sure if there is something else to do to make it persistent after
Thanks to anyone can help
Reply
#9
(2019-08-23, 06:51 AM)webber63 Wrote: Trying to solve the issue on my tinypilot I followed instructions available on pypilot wiki to get last version but had some further problem:
-I had to replace https:// in the url with git:// to manage to download the code
-building it I found what seems to be an error in servo.py line 600. I am not a big expert in Python but I think the ‘&&’ is the problem: removing one of two the error disappears.
-after updating communication still crashes if no waypoint is set in Garmin Plotter 
-I am not sure if update is persistent on tinypilot (due to tinycore linux),
Did not understwnd  which is the directory with actual installation to check if scripts are updated,
and I am not sure if there is something else to do to make it persistent after
Thanks to anyone can help

Well, struggling, reburning  the SD image every time it didn't reboot and other attempts eventually I managed to update it using 'git pull', pypilot.build and 'sudo python setup.py install' into the /home/tc/pypilot


Only, LCD display doesn't work anymore showing only the pypilot logo and nothing else.
I guess neither irc does, but can't test.
The webapp seems to work.
Someone has an idea of what's happened?
Thanks
Reply
#10
I do not have && on line servo.py:600.


The code in git should treat GPAPB differently from other **APB messages.

For the crashes, can you stop pypilot from command line:
sudo sv d pypilot

then:
cd ~/pypilot/pypilot
python autopilot.py

Make it crash now, and post the backtrace.


The lcd code is maybe broken in git at the moment which explains why display is not working. I was rewriting to support different lcd displays and the line in ugfx.cpp:764 should be uncommented.

Sean
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)