Waf crashes on Copter 3.6.5

Hi everyone,
I have a fork of ArduCopter 3.6.5, where I want to add some modifications for a new Altitude Control.
I have followed the instructions of http://ardupilot.org/dev/docs/building-setup-linux.html#install-some-required-packages (appearently the path of the script changed, so I installed the prereqs from ardupilot$ Tools/scripts/install-prereqs-ubuntu.sh -y instead of the path given in the link).

when I want to configure waf by executing ardupilot$ ./waf configure --board=sitl I get the following error:

File "/home/crowdsweeper/git/ardupilot-Copter_3_6_5-AltCS/ardupilot/modules/waf/waflib/Node.py", line 683, in ant_glob

ret = [x for x in self.ant_iter(accept=accept, pats=[to_pat(incl), to_pat(excl)], 
maxdepth=kw.get('maxdepth', 25), dir=dir, src=src, remove=kw.get('remove', True))]
  File "/home/crowdsweeper/git/ardupilot-Copter_3_6_5-AltCS/ardupilot/modules/waf/waflib/Node.py", line 683, in <listcomp>
    ret = [x for x in self.ant_iter(accept=accept, pats=[to_pat(incl), to_pat(excl)],         
maxdepth=kw.get('maxdepth', 25), dir=dir, src=src, remove=kw.get('remove', True))]
RuntimeError: generator raised StopIteration

`

When I searched for relatic topics in this forum and on google, I only found uavcan-related posts (eg http://ardupilot11.rssing.com/chan-63882339/all_p566.html). As ./waf list_boards throws same python exception, I think this is a different issue.

My system:

  • OS: ubuntu 16.04
  • ArduCopter version: Copter-3.6.5 tag

I also edited the ardupilot/waf file, to run with #!/usr/bin/python2 and with #!/usr/bin/python3, respectively, and it threw the same exception.

Do you know, how I can fix this?

Regards, Peter

EDIT:
Might this be a python- or pip-version related issue?
I forked Copter 3.6.11 as described above, and the same error happened.

1 Like

Update:
This issue: https://github.com/mpv-player/mpv/issues/5958 seems to cause a similar error, and I don’t quiet understand the solution there.

Appearently there is some waf-compatibility issue, due to a different generator behavior in python 3.7, when compared to older python versions, as mentioned here: https://stackoverflow.com/questions/51700960/runtimeerror-generator-raised-stopiteration-every-time-i-try-to-run-app

Did anyone encounter something like that, and is there some workaround, or perhaps some way to force waf to use python2? editing the ardupilot/waf file’s first line to #!/usr/bin/python2, as mentioned above, didn’t work, the generator error is still there.
Should I force all waf-related files to use python2? This seems ugly, but less dangerous than messing around with my python versions.

1 Like

Update:
After around 5 hours and some cups of coffee I got it to work.

The issue is a backward compatibility problem of python 3.7’s behavior concerning iterators, as I wrote in my first update (see https://stackoverflow.com/questions/51700960/runtimeerror-generator-raised-stopiteration-every-time-i-try-to-run-app and https://www.juandebravo.com/2018/11/09/python-37-stop-iteration/ for more info).

Because the waf-repo used by ardupilot hasn’t been updated in the last time, probably python 3.7 wasn’t an issue back then. It just surprises me a bit that nobody encountered this error here, when trying to compile ArduCopter, using waf and python 3.7 (or maybe I din’t search well enough).

I decided to fix the files for the new generator behavior and another minor fault, which might also be python version related.

  1. Fix generators
    1.1. in ardupilot/modules/waf/waflib/Node.py
    replace yield <object> (note that <object> is a placeholder for the object that is to be yielded) with

     try:
         yield <object>
     except StopIteration:
         return
    

within Node.ant_iter method (ca. line 590).
This occurs 3 times, 2 times with node as , 1 time with k as .
Then replace raise StopIteration with return in the method’s last line.


there might be other occurences, but I didn’t search for any others for now, as the code compiled with changeing only this file.

  1. fixing error with os.path.isfile
    After 1. the build started, but threw an exception at "Checking for program ‘rsync’:

     File "/home/crowdsweeper/git/ardupilot-Copter_3_6_11-AltCS/ardupilot/wscript", line 258, in configure
         _collect_autoconfig_files(cfg)
       File "/home/crowdsweeper/git/ardupilot-Copter_3_6_11-AltCS/ardupilot/wscript", line 160, in         _collect_autoconfig_files
         if p in cfg.files or not os.path.isfile(p):
       File "/home/crowdsweeper/anaconda3/lib/python3.7/genericpath.py", line 30, in isfile
         st = os.stat(path)
     TypeError: stat: path should be string, bytes, os.PathLike or integer, not NoneType
     SIM_VEHICLE: (Configure waf) exited with code 512
     SIM_VEHICLE: Killing tasks
    

. I don’t know, wether os.path.isfile also changed its behavior in not accepting NoneType objects, I just changed 1 line in ardupilot/wscript, in method _collect_autoconfig_files, (ca. line 163):
I replaced if p in cfg.files or not os.path.isfile(p): with

    if p in cfg.files or p is None or not os.path.isfile(p):

Now it doesn’t crash anymore, when p is None.


sitl runs now, I didn’t try to compile and run it on my CubeBlack, but for that I probably have to fix the waf files accordingly.

PS:
Do you think I should contact the waf-developers, as others might also encounter this?

1 Like

Annex:
StopIteration is also raised when compiling for CubeBlack. To fix that, modules/uavcan/libuavcan/dsdl_compiler/libuavcan_dsdl_compiler/__init__.py has to be edited in the final part of the file.

last = next(it)

has to be replaced by

try:
    last = next(it)
except StopIteration:
    return

The list of files to be edited is not final.

Can you please open a github pull request with your modifications?

1 Like

I hope I can do it this or next week