Support Raspberry Pi #366

Closed
ThomasJClark opened this Issue Jan 15, 2016 · 147 comments
@ThomasJClark
Contributor

It would be cool if GRIP ran on a Raspberry Pi. To do this, we need:

  • A Pi build of libntcore
  • A Pi build of JavaCV
  • A more flexible deploy too
    • Probably with defaults suited to the roborio, but have the username/password/directories customizable

GRIP would likely only work in headless mode (I don't think JavaFX is supported on arm/linux)

@bradamiller
Member

I have a pi set aside to bring in tomorrow anticipating this discussion. I wonder if it would work as a test if we created the directories on the pi so it looks like a roboRIO?

Brad

_____________________________

From: Thomas Clark notifications@github.com
Sent: Thursday, January 14, 2016 9:14 PM
Subject: [GRIP] Support Raspberry Pi (#366)
To: WPIRoboticsProjects/GRIP grip@noreply.github.com

It would be cool if GRIP ran on a Raspberry Pi. To do this, we need: A Pi build of libntcore A Pi build of JavaCV A more flexible deploy tool Probably with defaults suited to the roborio, but have the username/password/directories customizable

GRIP would likely only work in headless mode (I don't think JavaFX is supported on arm/linux)


Reply to this email directly or view it on GitHub.

@ThomasJClark ThomasJClark self-assigned this Jan 15, 2016
@ThadHouse

Pi 1 will not work for sure, It's Arm v6 whereas the RoboRIO is Arm v7. I did try RoboRIO ntcore builds on a BeagleBoneBlack, and they did not work either. I'm guessing because of the VFP vs HardFloat differences. I'm actually setting up a build server to build ntcore for Armv7 hf and android. The builds I'm building can be found here http://198.199.94.5/ntcore/ if you want to try them out. The arm-linux-gnueabihf should be the builds that work on the Pi 2. They will not work on a Pi 1, but I will look at trying to find a Pi 1 cross compiler, and then can add it really easily.

@JLLeitschuh
Member

The deploy script is already incredibly flexible. The UI components are extensible. I could probably get this working in ~1.5 hours.
(Getting the UI to look right will probably take the most time)

@bradamiller
Member

I wouldn't spend much time on a pi 1 build where the the performance is so much less and a pi 2 is only $40. Maybe I'll have time to play with it over the weekend, but I'm bring a few pi 2 boards if the grip guys want to try.

@ThadHouse

I just a bit of testing. Running my build on a BeagleBone Black started to load correctly, however then gave an error saying libstdc++.so.6 wasn't right. Spent a while trying to debug that, but couldn't. Don't know enough linux to debug that more. The cross compiler was GCC 4.9.3, but my BBB only had 4.9.2, and I couldn't figure out how to upgrade it. Hopefully it works on a Pi 2, or you can get GCC 4.9.3 onto it.

I also retested the RoboRIO image on the BBB. It gave a bad format error when trying to load. So that build will almost certainly not work on a Pi.

@ThadHouse

I added a zip of the lib folder used for cross compiling to the ntcore folder. That should have all the libraries needed if any more are needed.

@ThadHouse

Ok. So by preloading the libstdc++.so.6 in the zip folder, the cross compiled version started working on my BeagleBone Black. So the builds should work on Pi 2 either without issues, or require preloading a library before running, which shouldn't be too bad.

EDIT: Tested on my brand new CHIP as well, and the builds worked there too, as long as you had the specific libstdc++.so.6. So I put that file alone in the ntcore directory. And all you should need to do is when you run the program set LD_LIBRARY_PATH to whatever folder you put that library in.

@Code1010

Could you elaborate on the process you used to get this working on the BBB/Pi 2?

We have been attempting to re-build with some of the suggestions in this thread to no avail.

@ThadHouse

I didn't test getting the full GRIP suite working. I was only doing testing to see if I could get NetworkTables working properly.

@multiplemonomials

I also got an error message about how the JVM couldn't load the libraries when I tried GRIP on my Beaglebone Black (running Arch Linux). However, ThadHouse's ntcore.so and libstdc++ didn't fix it for me. Then, I tried rebuilding ntcore on the BBB, and using that .so file fixed the error message about ntcore.so. I then rebuilt all of OpenCV and the JavaCPP bindings (javacpp-presets) using arm-linux-gnueabihf-gcc from the AUR in an Arch VM, and then substituted them into the GRIP jar file. It WORKED! I guess the libjniopencv_foo libraries in opencv-3.0.0-1.1-linux-frc.jar have the wrong ABI for the BBB (and others?).

If you want to try it, just scp the this file and a GRIP save file onto your coprocessor, and run with

java -jar GRIP-archlinuxarm-deployable.jar test.grip
@ThadHouse

You should have been able to use the jar in the Java folder, but maybe it doesn't support Arch. I've only ever tested it on Debian based OS's, and only the actual library, not the jar. I'll try the jar tonight on my BBB and Pi 2.

And it's not surprising that the FRC jar does not work. The RIO is is Soft Float, whereas Pi's and BBBs are Hard Float.

@multiplemonomials

It was a journey, but I completed the first two items on your list of what was necessary for Raspberry Pi support. I built NTCore, opencv, and the OpenCV JavaCPP Preset for linux-arm. Not entirely sure about the ABI, these were compiled with GCC 5.3.0 arm-linux-gnueabihf on Arch Linux. I also added the prebuilt natives (which existed for every platform except linux-arm), and edited the build.gradle file to add all of this stuff into the jar. I changed the core project dependencies block to this:

dependencies {
        compile name: 'javacpp-opencv-preset'

        compile name: 'NetworkTables-3.0.0-natives-arm'    
        compile name: 'opencv-natives-linux-arm-hardfloat'
        compile name: 'opencv-natives-linux-x86'
        compile name: 'opencv-natives-linux-x86_64'
        compile name: 'opencv-natives-macosx-x86_64'
        compile name: 'opencv-natives-windows-x86'
        compile name: 'opencv-natives-windows-x86_64'

        compile group: 'org.bytedeco', name: 'javacpp', version: '1.1'
        compile group: 'org.bytedeco', name: 'javacv', version: '1.1'
        compile group: 'org.python', name: 'jython', version: '2.7.0'
        compile group: 'com.thoughtworks.xstream', name: 'xstream', version: '1.4.8'
        compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.4'
        compile group: 'com.google.guava', name: 'guava', version: '18.0'
        // We use the no_aop version of Guice because the aop isn't avaiable in arm java
        // http://stackoverflow.com/a/15235190/3708426
        // https://github.com/google/guice/wiki/OptionalAOP
        compile group: 'com.google.inject', name: 'guice', version: '4.0', classifier: 'no_aop'
        compile group: 'com.google.inject.extensions', name: 'guice-assistedinject', version: '4.0'
        compile group: 'edu.wpi.first.wpilib.networktables.java', name: 'NetworkTables', version: '3.0.0-SNAPSHOT', classifier: 'desktop'
}

JavaCPP doesn't distinguish between hard and soft float ARM (I assume that's the crucial difference between the RPi and the RoboRIO), and there's no easy way to make it do so. Therefore, natives for the RoboRIO and other Linux boards cannot coexist in the same jar. I think it would make sense to have two jars that are deployable: one with some or all of the above natives, and one with just

        compile name: 'opencv-linux-arm-roborio'
        compile name: 'NetworkTables-3.0.0-natives-roborio'

The user could select whether to deploy to a "generic" coprocessor, which would use the multi-native file, or a RoboRIO specifically, which would use the other jar with just those natives.

Also, arm-linux does actually have OpenJFX, so using these libraries would allow GRIP's GUI to run on embedded Linux boards.

I hope this is useful to you, and I hope we can get this working. You can download the libs here.

Things I built:
javacpp-opencv-preset.jar: The Java code which interfaces directly with the native OpenCV libs
opencv-natives-linux-arm-hardfloat.jar: The OpenCV 3.0.0 library natives, and the JavaCPP-generated interface libraries
NetworkTables-3.0.0-natives-arm.jar: libntcore.so, built for linux-armhf

@ThadHouse

Did you cross compile any of those? Or were they all compiled natively? If cross, how'd you get GCC5.3 instead of 4.9.3, which is the newest I could find looking around. I would like to get rid of the libstdc++.so requirement of my build if possible.

@multiplemonomials

I cross compiled them with the latest arm-linux-gnueabihf-gcc available from the Arch User Repository.

@ThadHouse

So I can't get your copy working on raspbian either, without the LD_PRELOAD trick. I end up getting the same error I was getting, where it can't find a libstdc++.so.6 with CXXABI_1.3.9, which it looks like GCC 5 compiles to. Turns out my build was compiling with GCC 5 anyway, so I don't know why you couldn't get it working on yours. It seems like the binaries produced should be identical whether or not the cross compiler is hosted on arch or debian.

Also it looks like your NetworkTables-3.0.0-natives-arm.jar does not include any of the java files, and instead just libntcore.so. Is that right? Everytime I've built ntcore, it get a jar that include both the java files and the native library.

@multiplemonomials

Can you check what libstdc++ ABI version your Raspberry Pi is using? It looks like there's a command line option to set it.

And yeah, I just built the c++ (cmake) part of ntcore because that is all that's needed to run GRIP on armhf. I was having some issues getting the java (gradle) part to run.

@ThadHouse

Mines using the one from GCC 4.9. I can't find anywhere to install GCC 5 from for Raspbian currently. Thats why I was just grabbing the libstdc++.so.6 from the cross compiler itself, and preloading that one before running. I tried switching to the GCC 4.9 cross compiler, and it compiled, however it was generating an illegal instruction for some reason, so I need to figure that out. I don't know how easy its going to be to get a universal configuration working unless we do the preloading trick, which should work on any device. I'll install arch on my BBB sometime this week and try and find a universal solution that would work for the most devices.

What part of gradle were you having trouble running? Once I got java 8 installed, the only special thing I had to do was set -PcompilerPrefix=arm-linux-gnueabihf-, which changes from the frc prefix to the generic hf prefix.

@multiplemonomials

Can you post raspbian's libstdc++.so so I can see if I can figure out what ABI it's using?

@multiplemonomials

Update: Or just run

strings /usr/lib/libstdc++.so | grep CXXABI 

on the Pi and post the output.

EDIT: sorry for the repeated post, GitHub/Pale Moon was being weird.

@ThadHouse
CXXABI_1.3
CXXABI_1.3.1
CXXABI_1.3.2
CXXABI_1.3.3
CXXABI_1.3.4
CXXABI_1.3.5
CXXABI_1.3.6
CXXABI_1.3.7
CXXABI_1.3.8
CXXABI_TM_1
CXXABI_ARM_1.3.3

Those are what I get. And that is a fresh install of raspbian jessie with apt-get update and upgrade ran.

@multiplemonomials

OK, so according to this page, anything we compile with GCC 4.9.0 or earlier (not sure about 4.9.3) should be fine. I can also install that older version of libstdc++ into my toolchain.

@ThadHouse

Oh can I just copy paste that one into the toolchain? or would you need to add other files? I still don't know why the 4.9 cross compiler kept crashing. It compiled correctly, and technically ntcore will compile with GCC 4.8 as well. But I'll try coping in the older libstdc++ into my toolchain too to see if I can fix it. Heres the libstdc++ from my pi if you want to try it.

http://198.199.94.5/ntcore/PiLibStdC++.so/

@multiplemonomials

I don't know if that would work. You can try. The safest way would be to download gcc 4.9.0 and build and install libstdc++ from inside the source tree. I won't have time to try that until Thursday, though.

@multiplemonomials

libntcore.so.zip

Alright, try this ntcore library on your Pi. I installed libstdc++ 6.0.20 and used that to build ntcore:

cmake -DCMAKE_SHARED_LINKER_FLAGS="-L/usr/arm-linux-gnueabihf/oldc++/lib" -DCMAKE_CXX_FLAGS="-I/usr/arm-linux-gnueabihf/oldc++/include/c++/4.9.0 -I/usr/arm-linux-gnueabihf/oldc++/include/c++/4.9.0/arm-linux-gnueabihf" ..

It doesn't seem to require the CXXABI_1.3.9 symbol. If this works, I'll try rebuilding opencv.

@ThadHouse

You didn't link a library.

@multiplemonomials

Just updated my post.

@ThadHouse

Ok I'll try it in an hour or so hopefully. We'll want to build with optimizations if we do an official one, but that should hopefully work for testing.

@JLLeitschuh
Member

Thanks you guys for taking this on. We have a lot we are trying to fix. This would be an awesome feature to implement if we could get it automated as part of our deployment.

@multiplemonomials

I did some research, and I think the correct optimizations are -march=armv7-a -mtune=cortex-a7 -mfpu=neon (plus -O3 added by CMake in release mode). I attached the optimized version.
libntcore.so.zip

@multiplemonomials

Oh and by the way, I still can't build the Java part of ntcore.

➜  ntcore git:(master) ✗ gradle build
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel

FAILURE: Build failed with an exception.

* Where:
Script '/home/jamie/dev/ntcore/java/java.gradle' line: 21

* What went wrong:
A problem occurred evaluating script.
> Could not find property 'binaries' on task ':arm:jar'.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 6.451 secs
@ThadHouse

Oh. You want to be using the gradle wrapper ./gradlew. In addition, you want to set the custom compiler prefix by using -PcompilerPrefix=yourcompilerprefixhere. Also did you custom compile your 4.9? If so I might want some help setting it up, as if your build works I want to be able to build it.

@multiplemonomials

I downloaded GCC 4.9.0 and configured only in the libstdc++v3 subdirectory. I figured out I had to copy libgcc/gthr-posix.h to libgcc/gthr-default.h for this to work. Then, I installed to the /usr/arm-linux-gnueabi/oldc++ directory.

The commands I ran:

cd gcc-4.9.0
cp libgcc/gthr-posix.h libgcc/gthr-default.h
cd libstdc++-v3
mkdir build
cd build
../configure --prefix=/usr/arm-linux-gnueabihf/oldc++ --host=arm-linux-gnueabihf --enable-libstdcxx-threads
make
sudo make install

You still have to patch ntcore, though, because the LLVM headers included with ntcore try to use std::is_trivially_copyable because GCC is version 5. This doesn't work with the old c++ headers. Therefore, in ntcore/include/llvm/type_traits.h, you have to change lines 33 and 34 to

#if 0
@ThadHouse

Oh is it still using GCC 5 only with libstdc++ for 4.9? Interesting.

@multiplemonomials

Using gradlew did fix it, but I have no idea why. The one I have installed is v2.10, and gradlew uses v2.8. Does the newer version not work???

@ThadHouse

So with that build, I get an _undefined symbol: ZdlPvj when trying to load it. And I think the gradlew has some custom mods to it to enable some hidden settings. I think thats why you need the wrapper.

@ThadHouse

So I think if we do it right, the deploy can handle the LD_LOAD_LIBRARY required for a GCC 5 build. With the deploy changes is shouldn't be too difficult. However its going to require a separate GRIP build jar for sure. It will also probably require a button in the UI to switch between the RoboRIO and other devices. I don't know enough about Gradle or JavaFX to enable both of those things. @ThomasJClark would you be able to help with those? If so, I can get the deploy script added to where it should deploy right to the RIO and other ARM devices.

@ThomasJClark
Contributor

So I think if we do it right, the deploy can handle the LD_LOAD_LIBRARY required for a GCC 5 build. With the deploy changes is shouldn't be too difficult. However its going to require a separate GRIP build jar for sure. It will also probably require a button in the UI to switch between the RoboRIO and other devices. I don't know enough about Gradle or JavaFX to enable both of those things. @ThomasJClark would you be able to help with those? If so, I can get the deploy script added to where it should deploy right to the RIO and other ARM devices.

If I can get a link to whatever native libraries are working and what commands we need to run them, I think I can add it to the project

@BrianAtlanta

Just got our Pi. Which linux distro should we use. I thought I read Raspbian over on ChiefDelphi.

@ThadHouse

I only have the ntcore lib, which is here http://198.199.94.5/ntcore/cb4cc63/arm-linux-gnueabihf/java/ntcore-arm.jar. You should be able to use the OpenCV lib found here, made by multiplemonomials https://www.dropbox.com/s/flmcrzhzjou6b9y/GRIP-linux-arm-libs.zip?dl=0.

To make these compatible with most devices, you need to deploy this file http://198.199.94.5/ntcore/libstdc++.so.6 to the same directory you deploy the grip jar to. Then, when you run GRIP, your run command needs to become
env LD_LIBRARY_PATH=deploydirectory:LD_LIBRARY_PATH java -jar GRIP.jar (make sure to replace deploydirectiory with the directory you deployed to.)
and then whatever other arguments you need after that.

We'd been trying to get an ntcore build that didn't require the libstdc++.so.6, however everyway we tried it didn't work. We'll keep looking, but for now it looks like thats going to be the required solution.

@ThomasJClark
Contributor

👍

@EdWard680
Member

So I got GRIP to run on my Pi 2 Jessie, however it gives me this error at startup
SEVERE: NetworkTables: TCPConnector.cpp:157 select() to port 1735 error 111 - Connection refused
It's also unable to capture frames off my webcam, but that could be unrelated.
Is this related to a dependency issue? I can ping the address that publishAddress is set to in my project.grip settings from the pi, and the project successfully connects and publishes on my computer.

@ThadHouse

@EdWard680 Do you have the jar you attempted to deploy? ntcore works with me manually on my Pi, but I've never been able to build grip with the jar. Don't know enough about the Java build system. That's why I was hoping Thomas could get the build system working so I could test it.

@EdWard680
Member

Here it is
I used the method mentioned above to run it
env LD_LIBRARY_PATH=.:LD_LIBRARY_PATH java -jar core-1.1.1-all.jar

@multiplemonomials

Btw, I wrote a batch script to automate deploying the GRIP profile and starting GRIP. You guys might find it useful.

@multiplemonomials

Also, I'm pretty sure you're getting that Connection refused error because your NetworkTables publish address is wrong in GRIP.

@EdWard680
Member

I wish it were wrong but I've double checked it and it's right. I can ping that address from the Pi and I can open client viewer client on my computer for that address, and the values are successfully pushed from the UI

@multiplemonomials

Actually, you need to run the server at that address.

@multiplemonomials

Wait, I read your post wrong. You're running the server at the publish address, right? And you can access data on it from the client?

@EdWard680
Member

I have a roborio running the server on my lan. I have a laptop from which I composed the test grip file on my lan. And I have the Pi 2 to which I deployed that project.
I can access the data in outline viewer client on my laptop when it's running in the UI.
The Pi loads the file but shows that connection refused error. I can ping the deploy address from the pi

@vScourge

Thanks for all the efforts here! Has anyone got GRIP fully working/capturing on the Raspberry Pi 2?
I think we almost have GRIP 1.1.1 running on ours (using Linux Arm) but it's failing to initialize the camera (Logitech C920). The same camera works fine on the Pi 2 using ffmpeg. I've verified it's dev/video0, and our grip file is set to use camera 0. Any suggestions?

From the .grip file:

<sources>
  <grip:Camera>
    <property name="deviceNumber" value="0"/>
  </grip:Camera>
</sources>

Errors:

Loading Dependency Injection Framework
Jan 24, 2016 9:47:30 PM java.util.logging.LogManager$RootLogger log
CONFIG: Configuration done.
Jan 24, 2016 9:47:31 PM java.util.logging.LogManager$RootLogger log
CONFIG: GRIP Version: 1.1.1
platform: /Linux/arm/
Jan 24, 2016 9:47:40 PM edu.wpi.grip.core.Main start
INFO: Loading file test2.grip
Jan 24, 2016 9:47:44 PM edu.wpi.grip.core.Source initializeSafely
WARNING: Failed to initialize CameraSource
java.io.IOException: A problem occurred trying to start the frame grabber for Webcam 0
    at edu.wpi.grip.core.sources.CameraSource.start(CameraSource.java:191)
    at edu.wpi.grip.core.sources.CameraSource.initialize(CameraSource.java:174)
    at edu.wpi.grip.core.Source.initializeSafely(Source.java:98)
    at edu.wpi.grip.core.serialization.SourceConverter.unmarshal(SourceConverter.java:60)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
    at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.readItem(AbstractCollectionConverter.java:71)
    at com.thoughtworks.xstream.converters.collections.CollectionConverter.addCurrentElementToCollection(CollectionConverter.java:98)
    at com.thoughtworks.xstream.converters.collections.CollectionConverter.populateCollection(CollectionConverter.java:91)
    at com.thoughtworks.xstream.converters.collections.CollectionConverter.populateCollection(CollectionConverter.java:85)
    at com.thoughtworks.xstream.converters.collections.CollectionConverter.unmarshal(CollectionConverter.java:80)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:480)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:412)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:263)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)
    at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1206)
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1190)
    at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1061)
    at edu.wpi.grip.core.serialization.Project.open(Project.java:68)
    at edu.wpi.grip.core.serialization.Project.open(Project.java:62)
    at edu.wpi.grip.core.Main.start(Main.java:59)
    at edu.wpi.grip.core.Main.main(Main.java:41)
Caused by: org.bytedeco.javacv.FrameGrabber$Exception: cvCreateCameraCapture() Error: Could not create camera capture.
    at org.bytedeco.javacv.OpenCVFrameGrabber.start(OpenCVFrameGrabber.java:179)
    at org.bytedeco.javacv.FrameGrabber.restart(FrameGrabber.java:430)
    at edu.wpi.grip.core.sources.CameraSource.start(CameraSource.java:189)
    ... 28 more
@EdWard680
Member

Same exact thing happens for me. @vScourge Can you try getting Network Tables to publish?

@ThadHouse

Does anyone have an Axis Ethernet camera to use for testing? Our team uses them instead of the USB cameras, so I can't help camera capture issues.

@EdWard680
Member

I have an mpjeg stream I can generate but I haven't been able to get that to work with GRIP normally, let alone on a Pi

@vScourge

@EdWard680 I had left my publish step out to keep it simple, but putting it back in it now ends with this error:

SEVERE: NetworkTables: TCPConnector.cpp:157 select() to  port 1735 error 111 - Connection refused

... which isn't too surprising since I don't have a RoboRio running on this network yet? I can try that but maybe not until tomorrow.

@EdWard680
Member

You don't have to, but in order to test it you could start a Network Table server on your computer using Eclipse > WPILib > Outline Viewer and then tell GRIP to connect to that.

@multiplemonomials

We were able to get GRIP capturing images and publishing over networktables using a Beaglebone Black and an Axis M1013. When I tried the only USB camera we had on a Linux desktop, GRIP said it didn't support the color format.

@EdWard680
Member

@multiplemonomials Can you upload the core.jar you used?

@multiplemonomials

As I linked in an earlier post, https://www.dropbox.com/s/7iueslu26avp7d6/GRIP-archlinuxarm-deployable.jar?dl=0

This needs the libstdc++.so

@EdWard680
Member

My mistake. I thought those were just the dependencies

@multiplemonomials

Hey, waitaminute!
@ThadHouse, you said in an earlier post that you got an error about the symbol _ZdlPvj. I just realized, that's a mangled c++ name, and it unmangles to

 operator delete(void*, unsigned int)
@ThadHouse

Hmm. So I wonder why it couldn't find delete? If I compile something on my pi physically with GCC 4.9.2, it works, and the GCC 5 cross compiler works as log as the libstdc++.so is loaded, so I wonder where delete would be located for the compiler you built.

@multiplemonomials

Looking at the files, I get

➜  build  arm-linux-gnueabihf-nm /usr/arm-linux-gnueabihf/oldc++/lib/libstdc++.so | grep _Zdl | c++filt
00050e9c T operator delete(void*)
00050ec0 T operator delete(void*, std::nothrow_t const&)
0006956c t operator delete(void*, void*)
➜  build  arm-linux-gnueabihf-nm /usr/arm-linux-gnueabihf/lib/libstdc++.so | grep _Zdl | c++filt
0006e9b4 T operator delete(void*)
0006e9b8 T operator delete(void*, unsigned int)
0006e9bc T operator delete(void*, std::nothrow_t const&)

In other words, the signature of delete is different between the two files. From the one you took from your Pi:

➜  build  strings ~/Downloads/libstdc++.so.6.0.20 | grep _Zdl | c++filt
operator delete(void*)
operator delete(void*, std::nothrow_t const&)

operator delete(void*, unsigned int) is missing, which would explain the error.

@ThadHouse

Ah. So it would require a libstdc++.so.6 anyway. So no point in doing the custom GCC 4.9-GCC 5 mix. If we have to have the library, we'll have to provide a custom .so anyway, and can just use the stock arm-linux-gnueabihf gcc.

@multiplemonomials

Looks like this function is called a "placement delete" and is relatively new. See here. I commented its declaration out in the headers and rebuilt ntcore. No change. Still working on it.

@ThadHouse

One thing that potentially does help us is that the newest ntcore, if it fails to load the library built into the jar, it will attempt to load a libntcore.so from the current directory. So that means we might not have to have separate jars, at least for ntcore. We would have to have them still for OpenCV I think however.

@EdWard680
Member

I was able to get GRIP "processing" (publishing the frame rate of) an MPJEG stream on my Pi 2

@vScourge

@EdWard680 Awesome. What camera are you using? We're giving up on USB and trying an Axis tonight, see if we have better luck. Are you using any binaries different from what's been posted here earlier?

@EdWard680
Member

I posted the jar I compiled and I'm using the libntcore.so and the libstdc++.so posted most recently above. I had the same USB webcam problem you had, which is worth still investigating since I only get that issue on the Pi.
I used this program to stream an mpjeg stream from the Pi. It supports using a USB camera or the raspberry pi camera with a lot of configuration potential. Once you do that it's easy to view the stream in a browser, in Smart Dash, and in the GRIP previewer.

I tested it with an mpjeg stream generated from the raspberry pi camera, as well as one generated from the usb camera I'm using (ps3 eye) at the same quality and it worked great. I'm not sure how fast it actually is yet, as I haven't tried a vision algo yet

@multiplemonomials

OK, I think I figured out how to fix the dreaded _ZdlPvj issue. It may in fact have been an issue with my system headers. In new, I replaced

inline void operator delete(void*, void*) _GLIBCXX_USE_NOEXCEPT { }

with

inline void operator delete(void*, unsigned int) _GLIBCXX_USE_NOEXCEPT { }

Now everything more or less works. I got a libntcore.so that doesn't use _ZdlPvj. @ThadHouse , try this out:
libntcore.so.zip

@vScourge

@EdWard680 Were you also running GRIP on the Pi? We're running mjpeg-streamer now (with -b, to run in background) and it seems to be using the USB camera (light is on). We also have GRIP running on the Pi but it can't find the stream. We're using "localhost:8080" but the error says it's expecting the stream at "http://localhost:8080/mjpg/video.mjpg". GRIP fails saying that server is returning response 400.

We're looking for an option to change the output address in mjpeg-streamer, but no luck so far.

@EdWard680
Member

I was running GRIP on the Pi.
I was running it with
mjpg_streamer -o "output_http.so -w ./www -p 1180" -i "input_uvc -y -n -f 15 -r 640x480"
This allows you to access the stream at http://<pi-address>:1180/?action=stream
You should be able to view it in your browser, and you should be able to see it in GRIP preview by adding that as an IP camera. It should also work on the Pi. The address it's expecting is the one used by Axis, as long as you put the whole url in it overrides it I believe.

@vScourge

@EdWard680 Great, that did the trick, thank you very much. We're just down to some NetworkTable errors, since the robot isn't connected yet.

@ThadHouse

@multiplemonomials I still get the same error with that latest library too.

@multiplemonomials

What? How can that be? Are you sure you're trying the right file? According to nm, that library doesn't ever reference _ZdlPvj.

I rebuilt all of the other libraries as well. The new GRIP jar, with optimizations enabled so it should run much faster, is here.

@ThadHouse

Hmm. It must have extracted wrong. Now it attempts to load correctly, and nm shows now reference, however it immediately SegFaults on startup. Give me a minute to try and debug why.

@ThadHouse

Ok it gives the error I received when trying to cross compile with GCC 4.9. Program received signal SIGILL, Illegal instruction.

@ThadHouse

So compiling it native on my Pi with GCC 4.9 does work. I wonder if there's a bug in the GCC 4.9 cross compiler.

@multiplemonomials

Wait, why is that a segfault?

@ThadHouse

I don't know. When running code without gdb, it just prints Segmentation Fault and quits. Then if I run under GDB, thats when it shows that the program received SIGILL.

@multiplemonomials

You're just running ntcore, right? Not GRIP?

@ThadHouse

Yeah thats just getting ntcore working. A super simple program. Just linking to the so, and initializing NetworkTables.

@multiplemonomials

You're using a Pi 2, right? I'm going to try to compile without NEON.

@ThadHouse

Yeah its a Pi 2.

@ThadHouse

Same error.

@ThadHouse

That one works! What was the trick?

@multiplemonomials

That was compiled using the optimization flags for a rasberry pi 1. Are you ABSOLUTELY, POSITIVELY SURE that you have a pi 2?

@multiplemonomials

Try running

uname -m

on the pi.

@ThadHouse

It's definitely a Pi 2. ArmV7. The Pi 1 was V6. However I know that the raspbian on the Pi 2 was designed to run Pi 1 binaries, so maybe even it requires those flags to work. The GCC 5 library working with only the libstdc++.so makes even less sense if that is the case however.

@multiplemonomials

I could make 2 separate builds: one for the Pi 1 and the Pi 2 on Raspbian, and one for the Pi 2 on any other distro and the Beaglebone
Try this one:
libntcore-test4.so.zip

@ThadHouse

That download brings back the segmentation fault. Testing the builds on my BBB running debian to see if it has the same issue.

I'll be able to test that tomorrow on my Pi 1. But getting ntcore and GRIP working on a Pi 1 is going to be a lost cause anyway, as they are guaranteed to be too slow to actually work.

@ThadHouse

So builds 2 and 4 work properly on my BBB. Build 3 does not.

@multiplemonomials

OK, this one is with

-march=armv6j -mtune=generic-armv7-a -mfpu=vfp

libntcore-test5.so.zip

(the one that worked was with -mcpu-armv6j -mfpu=vfp)

@multiplemonomials

Build 1 was with -mfpu=neon, so I guess that's out. What's more concerning is that apparently the Pi and Beaglebone are completely incompatible.

@ThadHouse

Build 5 worked on Pi 2, but not on BBB

@ThadHouse

Build 1 works on my BBB too, which isn't surprising as I know the BBB supports neon. Thought the Pi 2 did as well.

@multiplemonomials

OK, this one is with -march=armv7-a -mfpu=neon-vfpv4. According to this thread, that should work on a Pi 2.
libntcore-test6.so.zip

Also, what happened when you tried to run build 5 on the BBB?

@ThadHouse

Build 5 had the Illegal instruction error on the BBB.

Build 6 has the Illegal instruction error on the Pi 2, and runs on the BBB.

@multiplemonomials

Something is really weird here. That command comes from the raspberry pi forums. Is your Pi up to date? Maybe you should see if a different distro, like Arch, fixes it. I'll try one more time.

@ThadHouse

Yeah I agree something is weird. I'll try Arch tomorrow. GCC 4.9 failing but GCC 5 working makes it even more odd.

@multiplemonomials

It might just be what you said, that Raspbian emulates the older architecture to the point where new code won't run. But then what about that forum thread??? Also, try your desktop gcc with -mcpu=generic-armv6j -mfpu=vfp and see if that fixes the illegal instruction error.

Last one, compiled without any CPU flags at all (since whatever the default was, it seemed to work):
libntcore-test7.so.zip

@ThadHouse

That build runs into the same Illegal Instruction issue on my BBB. Works properly on Pi 2. Old builds still have the same issues on the Pi 2 even after upgrading the Pi 2.

Also are those commands used when setting up cmake from the ntcore project? Don't know my way much around building with linux, and I've just been using the gradle builds since I don't have to do any configuring with those.

@multiplemonomials

Yeah, those are compiler options supplied with -DCMAKE_CXX_FLAGS=foo on the command line. I'm way, way more comfortable with cmake than gradle, so I'm using it to build ntcore as they thoughtfully provided both build systems. When you can, can you try Arch on your Pi, and retest builds 5 through 7 please? Anyway, I'm going to bed now, it's late. Good luck.

@bradamiller
Member

An interesting alternative to the Raspberry PI that works out of the box with GRIP and other tools, is much faster, and easier to use is called the Kangaroo. It's about $90 with an academic discount and I described using it here:

http://wpilib.screenstepslive.com/s/4485/m/50711/l/488429

Still needs a little more exploration, but is looking like a really good solution.

@ThadHouse

So @multiplemonomials Did the GCC 5 builds ever work for you on arch? I'll be able to test tonight your other builds, but it seems like either way we are going to have two options for Arm devices.

  1. GCC 5 build, and have the deploy load the GCC 5 libstdc++.so.6. This should work on all armv7 devices, and I've personally tested on everything I have. Would be nice if someone had a TX1 to test on, but it should work.
  2. GCC 4.9 build, with different builds specifically for Pi 2 running raspbian, and everything else running ArmV7. Wouldn't require a preload, but would require user selection between 3 different builds rather then 2. It's also looking like TX1 runs Ubuntu 14.04, which I think only has GCC 4.8, so might require even a 4th build for that, or preloading a library again.

@ThomasJClark and @JLLeitschuh, which option would you guys prefer for GRIP?

@ThomasJClark
Contributor

I think the first one would be good if the .so can be packaged in the JAR. Do you know if this is possible, or does it have to be preloaded when the Java command line is run?

@ThadHouse

I'm pretty sure it's not possible to package it in the JAR. Java loads the existing one on startup, and we can't load another one on top op that. Its possible to push a shell script to the device that would run it with the correct commands however.

@EdWard680
Member

So has anyone gotten GRIP to grab USB camera frames on a Pi/soft-arm device to work?

@multiplemonomials

Another option that you haven't mentioned is to separate the native libraries from the GRIP jar. Both ntcore and JavaCPP fall back to java.library.path if they can't find their libraries. You could put the native libraries in a set of directories, like "windows-x86", "macosx", "linux-arm-rpi2", "linux-arm-roborio", etc. At runtime, GRIP could make a detailed examination of the system it's running on and load the correct libraries by setting java.library.path before calling into any native code. Or, the user could specify the platform manually. Plus, you could deploy only the needed libraries, reducing the space used on the target device. We could also optimize the libraries properly for each cpu, as opposed to making a generic but less optimized Arm build (if it's even possible). The only real downside would be that the GRIP deployment would no longer be a single file.

I definitely prefer this option over the other two, it seems a bit cleaner.

@ryannazaretian

What is the status of the Raspberry Pi port of GRIP (JavaCV & libntcore)?

I think I have most of everything working, but I am getting a lot of Java exceptions when I launch the grip.jar file. I can't go into detail what the errors are until this evening.

If the project is working (this thread has been rather quiet), can we get some sort of guide as to the steps that need to be performed?

@vScourge
vScourge commented Feb 1, 2016

This page was recently created, and covers all the steps.
https://github.com/WPIRoboticsProjects/GRIP/wiki/Running-GRIP-on-a-Raspberry-Pi-2

Post details on your java exceptions when you can, maybe we can help.

@ryannazaretian

Awesome work! I'll add details on our Java exceptions if we have them after following the guide.

@ryannazaretian

Okay. I followed the instructions but I'm still having trouble.

Here's what works:
mjpg-streamer is working and the stream is available at http://raspberrypi.local:1180/?action=stream
GRIP on the RPi sort of works. I'm able to see the NT variables produced by Java.

Unforuntatly, I haven't figured out how to connect GRIP to mjpg-streamer (currently using the address above).

I'm also getting a few exceptions:

> pi@raspberrypi:~/vision $ ./start_grip.sh
> pi@raspberrypi:~/vision $ Loading Dependency Injection Framework
> Feb 01, 2016 11:14:14 PM java.util.logging.LogManager$RootLogger log
> CONFIG: Configuration done.
> Feb 01, 2016 11:14:14 PM java.util.logging.LogManager$RootLogger log
> CONFIG: GRIP Version: 1.1.1
> platform: /Linux/arm/
> Feb 01, 2016 11:14:18 PM edu.wpi.grip.core.Main start
> INFO: Loading file /home/pi/vision/grip/project.grip
> Feb 01, 2016 11:14:20 PM edu.wpi.grip.core.Main onExceptionEvent
> SEVERE: src must have a value to run this step.
> Feb 01, 2016 11:14:20 PM edu.wpi.grip.core.Main onExceptionEvent
> SEVERE: src must have a value to run this step.
> Feb 01, 2016 11:14:20 PM edu.wpi.grip.core.Main onExceptionEvent
> SEVERE: src must have a value to run this step.
> Feb 01, 2016 11:14:20 PM edu.wpi.grip.core.Main onExceptionEvent
> SEVERE: src must have a value to run this step.
> Feb 01, 2016 11:14:20 PM edu.wpi.grip.core.Main onExceptionEvent
> SEVERE: Input must have a value to run this step.
> Feb 01, 2016 11:14:20 PM edu.wpi.grip.core.Main onExceptionEvent
> SEVERE: Input must have a value to run this step.
> Feb 01, 2016 11:14:20 PM edu.wpi.grip.core.Main onExceptionEvent
> SEVERE: Input must have a value to run this step.
> Feb 01, 2016 11:14:20 PM edu.wpi.grip.core.Main onExceptionEvent
> SEVERE: Input must have a value to run this step.
> Feb 01, 2016 11:14:20 PM edu.wpi.grip.core.Main onExceptionEvent
> SEVERE: Input must have a value to run this step.
> Feb 01, 2016 11:14:20 PM edu.wpi.grip.core.Main onExceptionEvent
> SEVERE: Input must have a value to run this step.
> Feb 01, 2016 11:14:20 PM edu.wpi.grip.core.Main onExceptionEvent
> SEVERE: Value must have a value to run this step.
> Feb 01, 2016 11:14:20 PM edu.wpi.grip.core.Main onExceptionEvent
> SEVERE: Value must have a value to run this step.
> Feb 01, 2016 11:14:20 PM edu.wpi.grip.core.Main onExceptionEvent
> SEVERE: Value must have a value to run this step.
> Feb 01, 2016 11:14:20 PM edu.wpi.grip.core.Main onExceptionEvent
> SEVERE: Value must have a value to run this step.
> Feb 01, 2016 11:14:20 PM edu.wpi.grip.core.Main onExceptionEvent
> SEVERE: Value must have a value to run this step.
> Feb 01, 2016 11:14:20 PM edu.wpi.grip.core.Main onExceptionEvent
> SEVERE: Value must have a value to run this step.
> Feb 01, 2016 11:14:21 PM edu.wpi.grip.core.Main onExceptionEvent
> SEVERE: Value must have a value to run this step.
> Feb 01, 2016 11:14:21 PM edu.wpi.grip.core.Main onExceptionEvent
> SEVERE: Value must have a value to run this step.
> Feb 01, 2016 11:14:21 PM edu.wpi.grip.core.Main onExceptionClearedEvent
> INFO: Exception Cleared Event
> OpenCV Error: Assertion failed (ssize.area() > 0) in resize, file /home/jamie/dev/javacpp-presets-master/opencv/cppbuild/linux-arm/opencv-3.0.0/modules/imgproc/src/imgwarp.cpp, line 3208
> Feb 01, 2016 11:14:21 PM edu.wpi.grip.core.Step runPerformIfPossible
> WARNING: The CV resize operation did not perform correctly.
> java.lang.RuntimeException: /home/jamie/dev/javacpp-presets-master/opencv/cppbuild/linux-arm/opencv-3.0.0/modules/imgproc/src/imgwarp.cpp:3208: error: (-215) ssize.area() > 0 in function resize
> 
>         at org.bytedeco.javacpp.opencv_imgproc.resize(Native Method)
>         at edu.wpi.grip.generated.opencv_imgproc.Resize.perform(Resize.java:58)
>         at edu.wpi.grip.core.Operation.perform(Operation.java:61)
>         at edu.wpi.grip.core.Step.runPerformIfPossible(Step.java:137)
>         at edu.wpi.grip.core.Step.onInputSocketChanged(Step.java:156)
>         at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
>         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>         at java.lang.reflect.Method.invoke(Method.java:483)
>         at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74)
>         at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47)
>         at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322)
>         at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304)
>         at com.google.common.eventbus.EventBus.post(EventBus.java:275)
>         at edu.wpi.grip.core.serialization.ConnectionConverter.unmarshal(ConnectionConverter.java:58)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
>         at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.readItem(AbstractCollectionConverter.java:71)
>         at com.thoughtworks.xstream.converters.collections.CollectionConverter.addCurrentElementToCollection(CollectionConverter.java:98)
>         at com.thoughtworks.xstream.converters.collections.CollectionConverter.populateCollection(CollectionConverter.java:91)
>         at com.thoughtworks.xstream.converters.collections.CollectionConverter.populateCollection(CollectionConverter.java:85)
>         at com.thoughtworks.xstream.converters.collections.CollectionConverter.unmarshal(CollectionConverter.java:80)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
>         at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:480)
>         at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:412)
>         at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:263)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)
>         at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
>         at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1206)
>         at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1190)
>         at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1061)
>         at edu.wpi.grip.core.serialization.Project.open(Project.java:68)
>         at edu.wpi.grip.core.serialization.Project.open(Project.java:62)
>         at edu.wpi.grip.core.Main.start(Main.java:59)
>         at edu.wpi.grip.core.Main.main(Main.java:41)
> 
> Feb 01, 2016 11:14:21 PM edu.wpi.grip.core.Main onExceptionEvent
> SEVERE: The CV resize operation did not perform correctly.
> java.lang.RuntimeException: /home/jamie/dev/javacpp-presets-master/opencv/cppbuild/linux-arm/opencv-3.0.0/modules/imgproc/src/imgwarp.cpp:3208: error: (-215) ssize.area() > 0 in function resize
> 
>         at org.bytedeco.javacpp.opencv_imgproc.resize(Native Method)
>         at edu.wpi.grip.generated.opencv_imgproc.Resize.perform(Resize.java:58)
>         at edu.wpi.grip.core.Operation.perform(Operation.java:61)
>         at edu.wpi.grip.core.Step.runPerformIfPossible(Step.java:137)
>         at edu.wpi.grip.core.Step.onInputSocketChanged(Step.java:156)
>         at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
>         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>         at java.lang.reflect.Method.invoke(Method.java:483)
>         at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74)
>         at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47)
>         at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322)
>         at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304)
>         at com.google.common.eventbus.EventBus.post(EventBus.java:275)
>         at edu.wpi.grip.core.serialization.ConnectionConverter.unmarshal(ConnectionConverter.java:58)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
>         at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.readItem(AbstractCollectionConverter.java:71)
>         at com.thoughtworks.xstream.converters.collections.CollectionConverter.addCurrentElementToCollection(CollectionConverter.java:98)
>         at com.thoughtworks.xstream.converters.collections.CollectionConverter.populateCollection(CollectionConverter.java:91)
>         at com.thoughtworks.xstream.converters.collections.CollectionConverter.populateCollection(CollectionConverter.java:85)
>         at com.thoughtworks.xstream.converters.collections.CollectionConverter.unmarshal(CollectionConverter.java:80)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
>         at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:480)
>         at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:412)
>         at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:263)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)
>         at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
>         at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1206)
>         at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1190)
>         at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1061)
>         at edu.wpi.grip.core.serialization.Project.open(Project.java:68)
>         at edu.wpi.grip.core.serialization.Project.open(Project.java:62)
>         at edu.wpi.grip.core.Main.start(Main.java:59)
>         at edu.wpi.grip.core.Main.main(Main.java:41)
> 
> Feb 01, 2016 11:14:21 PM edu.wpi.grip.core.Step runPerformIfPossible
> WARNING: The HSL Threshold operation did not perform correctly.
> java.lang.IllegalArgumentException: HSL Threshold needs a 3-channel input
>         at edu.wpi.grip.core.operations.composite.HSLThresholdOperation.perform(HSLThresholdOperation.java:68)
>         at edu.wpi.grip.core.Step.runPerformIfPossible(Step.java:137)
>         at edu.wpi.grip.core.Step.onInputSocketChanged(Step.java:156)
>         at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
>         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>         at java.lang.reflect.Method.invoke(Method.java:483)
>         at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74)
>         at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47)
>         at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322)
>         at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304)
>         at com.google.common.eventbus.EventBus.post(EventBus.java:275)
>         at edu.wpi.grip.core.serialization.ConnectionConverter.unmarshal(ConnectionConverter.java:58)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
>         at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.readItem(AbstractCollectionConverter.java:71)
>         at com.thoughtworks.xstream.converters.collections.CollectionConverter.addCurrentElementToCollection(CollectionConverter.java:98)
>         at com.thoughtworks.xstream.converters.collections.CollectionConverter.populateCollection(CollectionConverter.java:91)
>         at com.thoughtworks.xstream.converters.collections.CollectionConverter.populateCollection(CollectionConverter.java:85)
>         at com.thoughtworks.xstream.converters.collections.CollectionConverter.unmarshal(CollectionConverter.java:80)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
>         at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:480)
>         at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:412)
>         at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:263)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)
>         at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
>         at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1206)
>         at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1190)
>         at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1061)
>         at edu.wpi.grip.core.serialization.Project.open(Project.java:68)
>         at edu.wpi.grip.core.serialization.Project.open(Project.java:62)
>         at edu.wpi.grip.core.Main.start(Main.java:59)
>         at edu.wpi.grip.core.Main.main(Main.java:41)
> 
> Feb 01, 2016 11:14:21 PM edu.wpi.grip.core.Main onExceptionEvent
> SEVERE: The HSL Threshold operation did not perform correctly.
> java.lang.IllegalArgumentException: HSL Threshold needs a 3-channel input
>         at edu.wpi.grip.core.operations.composite.HSLThresholdOperation.perform(HSLThresholdOperation.java:68)
>         at edu.wpi.grip.core.Step.runPerformIfPossible(Step.java:137)
>         at edu.wpi.grip.core.Step.onInputSocketChanged(Step.java:156)
>         at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
>         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>         at java.lang.reflect.Method.invoke(Method.java:483)
>         at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74)
>         at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47)
>         at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322)
>         at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304)
>         at com.google.common.eventbus.EventBus.post(EventBus.java:275)
>         at edu.wpi.grip.core.serialization.ConnectionConverter.unmarshal(ConnectionConverter.java:58)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
>         at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.readItem(AbstractCollectionConverter.java:71)
>         at com.thoughtworks.xstream.converters.collections.CollectionConverter.addCurrentElementToCollection(CollectionConverter.java:98)
>         at com.thoughtworks.xstream.converters.collections.CollectionConverter.populateCollection(CollectionConverter.java:91)
>         at com.thoughtworks.xstream.converters.collections.CollectionConverter.populateCollection(CollectionConverter.java:85)
>         at com.thoughtworks.xstream.converters.collections.CollectionConverter.unmarshal(CollectionConverter.java:80)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
>         at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:480)
>         at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:412)
>         at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:263)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
>         at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)
>         at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
>         at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1206)
>         at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1190)
>         at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1061)
>         at edu.wpi.grip.core.serialization.Project.open(Project.java:68)
>         at edu.wpi.grip.core.serialization.Project.open(Project.java:62)
>         at edu.wpi.grip.core.Main.start(Main.java:59)
>         at edu.wpi.grip.core.Main.main(Main.java:41)
> 
> Feb 01, 2016 11:14:21 PM edu.wpi.grip.core.Main onExceptionClearedEvent
> INFO: Exception Cleared Event
> Feb 01, 2016 11:14:21 PM edu.wpi.grip.core.Main onExceptionClearedEvent
> INFO: Exception Cleared Event
> Feb 01, 2016 11:14:21 PM edu.wpi.grip.core.Main onExceptionClearedEvent
> INFO: Exception Cleared Event
> Feb 01, 2016 11:14:21 PM edu.wpi.grip.core.operations.networktables.NTManager lambda$new$8
> SEVERE: NetworkTables: TCPConnector.cpp:157 select() to  port 1735 error 111 - Connection refused
> Feb 01, 2016 11:14:21 PM edu.wpi.grip.core.Main start
> INFO: SUCCESS! The project is running in headless mode!
> Feb 01, 2016 11:14:23 PM edu.wpi.grip.core.operations.networktables.NTManager lambda$new$8
> INFO: NetworkTables: Dispatcher.cpp:392 client: CONNECTED to server 129.252.23.127 port 1735
@cartycrabber

Same as @ryannazaretia I am unable to get the mjpg stream to work with GRIP. I use the same address, but when attempting to view the image in GRIP this is what is shown:

image

@EdWard680
Member

If you're running with a static image it only runs the pipeline once, and the first run of the pipeline usually throws an exception at every step. If they merge #392 into the next release I think it fixes that.

The mjpg error is another issue a lot of teams have been having if they run it on Win7 which should be fixed in #456 this pull request I believe.

@ThomasJClark @JLLeitschuh Can you confirm that these pull requests will likely fix these issues?
I've only tested this method on Ubuntu and Win10, unfortunately

@ThomasJClark
Contributor

I believe #392 will fix this, although I'm not sure if @JLLeitschuh is done working on it

@ryannazaretian

Just so this is documented. I have GRIP running on our RPi2. As @EdWard680 stated, it throws an error on each part of the pipeline, but just once. Not sure why, but if I set the address in the IP camera, close GRIP, and reopen it, it will display the image correctly. I know there is a fix for the IP camera in the next release.

While it runs, I wouldn't say it works. I'm seeing 100% utilization on one core of the RPi2 CPU and the vision processing results are delayed by 2 or 3 seconds when processing a 320x240 pixel image.

My pipeline is identical to the 2016 tutorial, minus the image resize. To avoid more CPU usage, I removed the image resize function from GRIP and I provide the source image from mjpg_streamer at the reduced 320x240 resolution. I can try running at 160x120, but at this point, we will start losing a lot of resolution from what GRIP provides in the contour report.

I've seen a commit that is supposed to run each pipeline step in its own process. This may help divide up the resources better rather than relying on one core to compute everything.

@ryannazaretian

Will the core-1.1.1-all.jar need to be recompiled for the RPi to support GRIP 1.2.0? (core-1.2.0-all.jar)

@ThomasJClark
Contributor

The native libraries have not changed at all between v1.1.1 and v1.2.0, you should just need the new Java .class files and other resources from the JAR

@EdWard680
Member

So what JVM arguments should be passed in in order to mitigate the need for having LD_LIBRARY_PATH=... before the grip command. I tried java.library.path=/home/pi/path/to/shared_libs/ and it gives me something like could not find .home.pi.path.to.shared_libs or something. Should I try just home/pi/path/to/libs or perhaps just . ?

@EdWard680
Member

Okay I realized that I had omitted the -D, but I still can't emulate the correct behavior with this setup

@ThadHouse

What errors are you getting? The LD_LIBRARY_PATH is not a JVM thing, and its at the native level, so you can't really get rid of it.

@EdWard680
Member

Actually, GRIP runs with the JVM args -Djava.library.path='/home/pi/path/to/grip' if I run the command in the same working directory as the grip jar and the shared libs (libntcore and libstdc++). If I run it from a different directory, it complains about not being able to find jniopencv_core in java.library.path

@ThadHouse

Hmm we'd have to look at the opencv code on why thats happening.

@EdWard680
Member

@ThomasJClark If the script which is deployed just did cd <deploy directory> first, then that would make it possible to run grip on the pi without a custom script, which would mean the deploy dialogue which runs it could be used, as well as the same robot code

@CraigJSmith

EDIT: I now have GRIP working on the Pi. The trick was switching to GRIP version 1.1.1. Strange thing is, I still get the HSL Threshold needs a 3-channel input error, but after a few seconds I get INFO: SUCCESS! The project is running in headless mode!. After that, no new errors occur. I tested to make sure that GRIP was actually working by reporting back framerate and contour information to NetworkTables, both worked fine.

It appears that GRIP 1.2 isn't allowing enough time for the camera to connect, and just gives up when it doesn't see it immediately. Whatever the case, thanks everyone for all the help especially in the Gitter chat.

I've been trying to get GRIP working on the Raspberry Pi for about a week now without much success. I keep getting the error.

WARNING: The HSL Threshold operation did not perform correctly. java.lang.IllegalArgumentException: HSL Threshold needs a 3-channel input at edu.wpi.grip.core.operations.composite.HSLThresholdOperation.perform(HSLThresholdOperation.java:68)

I am using a Raspberry Pi 2 B and have tried using Raspian Wheezy & Jessie, as well as Ubuntu Server. I have reinstalled and started over countless times with the same result.

I have tired using the MJPG camera server as suggested in the wiki as well as axis cameras, an android app, and various other web streams. In all these cases, I was able to access the camera stream without any issue in the GRIP gui interface, but not on the Pi.

Any help would be appreciated.

@robert1356

I have followed the install instructions. I'm running on a Pi 2+ with Raspian. mjpg-streamer is working fine, but when I launch GRIP, I'm getting the following shared object link errors:

Feb 14, 2016 6:27:38 PM java.util.logging.LogManager$RootLogger log
CONFIG: Configuration done.
Feb 14, 2016 6:27:38 PM java.util.logging.LogManager$RootLogger log
CONFIG: GRIP Version: 1.2.0-5-g3a658db
platform: /Linux/arm/
Feb 14, 2016 6:27:43 PM edu.wpi.grip.core.GRIPCoreModule onThreadException
SEVERE: Uncaught Exception on thread Thread[main,5,main]
com.google.inject.ProvisionException: Unable to provision, see the following errors:

  1. Error injecting constructor, java.lang.UnsatisfiedLinkError: /home/pi/vision/grip/libntcore.so: /lib/arm-linux-gnueabihf/libc.so.6: version GLIBC_2.17' not found (required by /home/pi/vision/grip/libstdc++.so.6) at edu.wpi.grip.core.operations.networktables.NTManager.<init>(Unknown Source) at edu.wpi.grip.core.operations.networktables.NTManager.class(Unknown Source) while locating edu.wpi.grip.core.operations.networktables.NTManager for field at edu.wpi.grip.core.Pipeline.ntManager(Unknown Source) at edu.wpi.grip.core.Pipeline.class(Unknown Source) while locating edu.wpi.grip.core.Pipeline for field at edu.wpi.grip.core.serialization.Project.pipeline(Unknown Source) at edu.wpi.grip.core.serialization.Project.class(Unknown Source) while locating edu.wpi.grip.core.serialization.Project for field at edu.wpi.grip.core.Main.project(Unknown Source) while locating edu.wpi.grip.core.Main Caused by: java.lang.UnsatisfiedLinkError: /home/pi/vision/grip/libntcore.so: /lib/arm-linux-gnueabihf/libc.so.6: versionGLIBC_2.17' not found (required by /home/pi/vision/grip/libstdc++.so.6)
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1929)
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1847)
    at java.lang.Runtime.loadLibrary0(Runtime.java:870)
    at java.lang.System.loadLibrary(System.java:1119)
@EdWard680
Member

What version of raspbian are you running?
On Feb 15, 2016 7:52 PM, "Robert Palmer Jr" notifications@github.com
wrote:

I have followed the install instructions. I'm running on a Pi 2+ with
Raspian. mjpg-streamer is working fine, but when I launch GRIP, I'm getting
the following shared object link errors:

Feb 14, 2016 6:27:38 PM java.util.logging.LogManager$RootLogger log
CONFIG: Configuration done.
Feb 14, 2016 6:27:38 PM java.util.logging.LogManager$RootLogger log
CONFIG: GRIP Version: 1.2.0-5-g3a658db
platform: /Linux/arm/
Feb 14, 2016 6:27:43 PM edu.wpi.grip.core.GRIPCoreModule onThreadException
SEVERE: Uncaught Exception on thread Thread[main,5,main]
com.google.inject.ProvisionException: Unable to provision, see the
following errors:

  1. Error injecting constructor, java.lang.UnsatisfiedLinkError:
    /home/pi/vision/grip/libntcore.so: /lib/arm-linux-gnueabihf/libc.so.6:
    version GLIBC_2.17' not found (required by
    /home/pi/vision/grip/libstdc++.so.6)
    at edu.wpi.grip.core.operations.networktables.NTManager.(Unknown
    Source)
    at edu.wpi.grip.core.operations.networktables.NTManager.class(Unknown
    Source)
    while locating edu.wpi.grip.core.operations.networktables.NTManager
    for field at edu.wpi.grip.core.Pipeline.ntManager(Unknown Source)
    at edu.wpi.grip.core.Pipeline.class(Unknown Source)
    while locating edu.wpi.grip.core.Pipeline
    for field at edu.wpi.grip.core.serialization.Project.pipeline(Unknown
    Source)
    at edu.wpi.grip.core.serialization.Project.class(Unknown Source)
    while locating edu.wpi.grip.core.serialization.Project
    for field at edu.wpi.grip.core.Main.project(Unknown Source)
    while locating edu.wpi.grip.core.Main
    Caused by: java.lang.UnsatisfiedLinkError:
    /home/pi/vision/grip/libntcore.so: /lib/arm-linux-gnueabihf/libc.so.6:
    versionGLIBC_2.17' not found (required by
    /home/pi/vision/grip/libstdc++.so.6)
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1929)
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1847)
    at java.lang.Runtime.loadLibrary0(Runtime.java:870)
    at java.lang.System.loadLibrary(System.java:1119)


Reply to this email directly or view it on GitHub
#366 (comment)
.

@CraigJSmith

When you deploy GRIP to the Pi, it never launches correctly. Try using
this command (edit it as needed)

env LD_LIBRARY_PATH=/home/pi/vision/grip:LD_LIBRARY_PATH java -jar
/home/pi/vision/grip/grip.jar /home/pi/code/grip/project.grip &

On 2/15/2016 7:52 PM, Robert Palmer Jr wrote:

I have followed the install instructions. I'm running on a Pi 2+ with
Raspian. mjpg-streamer is working fine, but when I launch GRIP, I'm
getting the following shared object link errors:

Feb 14, 2016 6:27:38 PM java.util.logging.LogManager$RootLogger log
CONFIG: Configuration done.
Feb 14, 2016 6:27:38 PM java.util.logging.LogManager$RootLogger log
CONFIG: GRIP Version: 1.2.0-5-g3a658db
platform: /Linux/arm/
Feb 14, 2016 6:27:43 PM edu.wpi.grip.core.GRIPCoreModule onThreadException
SEVERE: Uncaught Exception on thread Thread[main,5,main]
com.google.inject.ProvisionException: Unable to provision, see the
following errors:

  1. Error injecting constructor, java.lang.UnsatisfiedLinkError:
    /home/pi/vision/grip/libntcore.so: /lib/arm-linux-gnueabihf/libc.so.6:
    version |GLIBC_2.17' not found (required by
    /home/pi/vision/grip/libstdc++.so.6)
    at edu.wpi.grip.core.operations.networktables.NTManager.(Unknown
    Source)
    at edu.wpi.grip.core.operations.networktables.NTManager.class(Unknown
    Source)
    while locating edu.wpi.grip.core.operations.networktables.NTManager
    for field at edu.wpi.grip.core.Pipeline.ntManager(Unknown Source)
    at edu.wpi.grip.core.Pipeline.class(Unknown Source)
    while locating edu.wpi.grip.core.Pipeline
    for field at edu.wpi.grip.core.serialization.Project.pipeline(Unknown
    Source)
    at edu.wpi.grip.core.serialization.Project.class(Unknown Source)
    while locating edu.wpi.grip.core.serialization.Project
    for field at edu.wpi.grip.core.Main.project(Unknown Source)
    while locating edu.wpi.grip.core.Main
    Caused by: java.lang.UnsatisfiedLinkError:
    /home/pi/vision/grip/libntcore.so: /lib/arm-linux-gnueabihf/libc.so.6:
    version|GLIBC_2.17' not found (required by
    /home/pi/vision/grip/libstdc++.so.6)
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1929)
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1847)
    at java.lang.Runtime.loadLibrary0(Runtime.java:870)
    at java.lang.System.loadLibrary(System.java:1119)


Reply to this email directly or view it on GitHub
#366 (comment).

@robert1356

@EdWard680 I'm running:
Linux raspi2 3.18.11-v7+ #781 SMP PREEMPT Tue Apr 21 18:07:59 BST 2015 arm7l

@robert1356

@CraigJSmith yep, I'm doing that - I set up the script for launching GRIP. I'm running it from an ssh session.

@EdWard680
Member

The error is due to running an outdated libc. Easiest solution is to update
to the latest raspbian release with raspbian Jessie.
On Feb 15, 2016 7:59 PM, "Robert Palmer Jr" notifications@github.com
wrote:

@CraigJSmith https://github.com/CraigJSmith yep, I'm doing that - I set
up the script for launching GRIP. I'm running it from an ssh session.


Reply to this email directly or view it on GitHub
#366 (comment)
.

@robert1356

@EdWard680 Thanks for the pointer. Updated today and I'm back to the point I was last night. It appears that GRIP will now start, but I'm getting the following:

Loading Dependency Injection Framework
Feb 16, 2016 7:57:08 PM java.util.logging.LogManager$RootLogger log
CONFIG: Configuration done.
Feb 16, 2016 7:57:09 PM java.util.logging.LogManager$RootLogger log
CONFIG: GRIP Version: 1.2.0-5-g3a658db
platform: /Linux/arm/
Feb 16, 2016 7:57:14 PM edu.wpi.grip.core.Main start
INFO: Loading file /home/pi/vision/grip/project.grip
Feb 16, 2016 7:57:17 PM edu.wpi.grip.core.operations.composite.PublishVideoOperation lambda$new$40
WARNING: Address already in use
java.net.BindException: Address already in use
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387)
at java.net.ServerSocket.bind(ServerSocket.java:375)
at java.net.ServerSocket.(ServerSocket.java:237)
at java.net.ServerSocket.(ServerSocket.java:128)
at edu.wpi.grip.core.operations.composite.PublishVideoOperation.lambda$new$40(PublishVideoOperation.java:52)
at java.lang.Thread.run(Thread.java:745)

This is kind of strange - most people were reporting connection refused and I get Address already in use.

I have done the following:

manually start mjpg-streamer
manually start grip

Grip is configured to with the deploy address of 'raspi2.local.' NetworkTable server address is set to 10.38.24.21 (my computer). The RPi is connected directly to my computer via ethernet cable. I'm running the NetworkTable viewer in server mode on my laptop.

Unfortunately, the exception does not specify what address (or port) is being requested.

The grip process I'm running contains only two modules - IP camera (connected to the mjpg-streamer) and publish video

@robert1356

Issue solved - I looked at the GRIP code and found the solution:

Publish video attempts to create a connection socket on port 1180
The mjpg-streamer installation instructions indicates that you should use port 1180 to publish the stream from the USB camera - WRONG Both can't be publishing on the same port

I changed the mjpg-streamer port to 1179 and now it launches successfully and starts the pipeline

@EdWard680
Member

I suggest you use 5800-5810 based on FRC Control Systems rules

@robert1356

Is anyone working on fixing the USB Camera support? Using the mjpg-streamer works, but you're adding delay, which I would like to eliminate. Does anyone know what the issue is? I might have some time to dig into it if someone can sum up the issue.

@multiplemonomials

So, for the record, in case anyone else has these problems:
Today I tried to set up a USB camera with mjpg_streamer on my BBB. However, when I started GRIP, my log was filled with

 SEVERE: NetworkTables: TCPConnector.cpp:157 select() to roborio-3128-frc.local port 1735 error 111 - Connection refused

and no data appeared on the Outline Viewer. I puzzled for a bit, and then realized that my Beaglebone, running Arch Linux, did not have the mDNS package (avahi) installed, so it couldn't resolve the roborio. I installed the avahi package, and enabled it.

sudo systemctl enable avahi-daemon.service

After the first reboot, I could no longer ping my BBB via its hostname, so I took it off the robot, and it turned out that its memory was completely full. I freed up some space and rebooted, and things were working again. But, GRIP still couldn't talk to the roboRIO. SSHed into the Beaglebone, I discovered that I could not ping the roboRIO by its ipv6 or ipv4 addresses, either. It turns out that, since I was using the D-Link bridge in router mode, the D-Link wasn't handing out IP addresses, and unlike the roborio or my laptop, the BBB did not auto-assign itself one, apparently breaking networking. So I configured it to have a static IP (which involved disabling netctl, the method using it didn't seem to work), and I was finally able to ping the roboRIO by its ip address, and resolve it with avahi-resolve. Then my laptop died, so I couldn't test it it actually was fixed, but I'll try again soon.

TL;DR: the notorious select() error can be caused by not having mDNS and/or an IP address set up on the coprocessor.

@meanpenguin

Hi,

I would like to report success with a Raspberry Pi v3 Model B
All went pretty smooth ....

One hiccup. I used GRIP grip-1.3.0-rc2-x86_64.exe but since the replacement file corresponds to rc1, the ran into some problems with one of the pipelines (Specifically: Step name="Filter Contours" only goes to Socket 7 in RC1, but goes to Socket 11 on RC2). Installing core-1.3.0-rc1.exe to build the pipeline resolved the issues.

Suggestion: Keep the original core-1.3.0-rc1-all.jar file in the "development" box so you can utilize the mjpg-streamer source while developing your pipeline. But instead, after you deploy to the RP, copy the core-1.3.0-rc1-9-g48dd139-all.jar over the grip.jar.

Suggestion 2: You may want to edit the project.grip and change the address of the mjpg-streamer source to localhost ( ). YMMV.

@multiplemonomials
Any chance you can publish how you are compiling the three files that are uploaded to the dropbox.
core-1.3.0-rc1-9-g48dd139-all.jar
libntcore.so
libstdc++.so.6

Thanks All.....

@multiplemonomials
multiplemonomials commented Sep 6, 2016 edited

Funilly enough, I gave up on this because when I finally got it to run on my beaglebone, there was about a 45 second delay between input frames and output data.

libstdc++-6.so - I built (an older version of) the source code. It is distributed with the GCC compiler. Just go into the GCC source directory and run something like

cd libstdc++-v3
./configure --host=arm-linux-gnueabi

Make sure to build a version as old or older than what is in use on your coprocessor, or it won't work. ABIs are annoying.

NetworkTables -- built from the source from the NetworkTables github repository

@JLLeitschuh
Member

If anyone wants to build some simple installer that we can use to ship GRIP on a Raspberry PI I'm happy to host it on our release page.

@CraigJSmith

Maybe a Dockerfile or something would be nice.

On 9/6/2016 4:16 PM, Jonathan Leitschuh wrote:

If anyone wants to build some simple installer that we can use to ship
GRIP on a Raspberry PI I'm happy to host it on our release page.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#366 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AGMNHk1LLZITZFEgJe4jkAJY8_5MxW5Wks5qnco7gaJpZM4HFauV.

@multiplemonomials
multiplemonomials commented Sep 6, 2016 edited

The GRIP jar -- merged the GRIP core jar from the release with the libraries I'd built:

OpenCV is easy. You just have to tell CMake the cross compiler command and the compiler flags. It's (I think) cmake -DCMAKE_CXX_COMPILER=<cross g++ command> -DCMAKE_CXX_FLAGS=<compiler flags>.

The JavaCV OpenCV bindings, however , reek of an arcane evil. They're using a maven plugin to build and generate C++ code. If that's not evil I don't know what is. To get it to compile properly, you have to edit the pom.xml file and add some magic undocumented xml elements to set the compiler and flags. I don't remember what they are, but I do remember looking through the Compiler class to find them. I'll fire up the VM when I get home and post them.

@multiplemonomials

Ah, got it. It didn't require any XML edits. The command line to build the JavaCPP presets for OpenCV is

mvn install -projects .,opencv -Dplatform=linux-arm -Dplatform.compiler=<arm gcc command> -Dplatform.linkpath=<link paths> -Dplatform.includepath=<include paths>

Replace the text in <>brackets with the correct stuff for your system. Multiple paths can be given to the include and like paths separated by semicolons. You'll want to set the paths to point to your C++ library and OpenCV installation (if it's not in the system path). My command was

mvn install -projects .,opencv -Dplatform=linux-arm -Dplatform.compiler=arm-linux-gnueabihf-g++ -Dplatform.linkpath=/usr/arm-linux-gnueabihf/oldc++/lib -Dplatform.includepath=/usr/arm-linux-gnueabihf/oldc++/include/c++/4.9.0:/usr/arm-linux-gnueabihf/oldc++/include/c++/4.9.0/arm-linux-gnueabihf
@JLLeitschuh
Member

Is this information something that should live here:
https://github.com/WPIRoboticsProjects/GRIP/wiki/Running-GRIP-on-a-Raspberry-Pi-2

?

@kjm16216

Hi, I'm just getting started with this and trying to use the Raspberry Pi Camera. So far I have successfully streamed the camera to grip, applied the filters. Fighting through deployment right now but seeing as most of this is written to 1.1 or 1.2, have there been updates for ver 1.4 that obviate any part of the general guide?
Using a pi3.

@SamCarlberg SamCarlberg added the deploy label Dec 8, 2016
@SamCarlberg SamCarlberg closed this Jan 8, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment