Cannot get USB to work on Raspberry-Pi Zero with Coral Edge TPU - google-coral

I have cross compiled libedgetpu for Raspi-0 and I can run a minimal C++ program. However it does not detect any TPU's. (The Coral TPU is connected via USB port to the Pi-0).
pi#raspberrypi:~ $ lsusb
Bus 001 Device 004: ID 1a6e:089a Global Unichip Corp.
Bus 001 Device 003: ID 0bda:8153 Realtek Semiconductor Corp. RTL8153 Gigabit Ethernet Adapter
Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
I added some debug statements in the code, here is the output:
pi#raspberrypi:/tmp $ LD_LIBRARY_PATH=. ./minimal
1...
######## BuildFromFile..
libedgetpu/tflite/edgetpu_manager_direct.cc:242 #### EnumerateEdgeTpuInternal 1
libedgetpu/driver/driver_factory.cc:130 #### DriverFactory::GetOrCreate 1
libedgetpu/tflite/edgetpu_manager_direct.cc:250 #### EnumerateEdgeTpuInternal 2
libedgetpu/driver/driver_factory.cc:48 #### DriverFactory::Enumerate 1
libedgetpu/driver/driver_factory.cc:58 #### DriverFactory::Enumerate device_list.size:0
libedgetpu/tflite/edgetpu_manager_direct.cc:252 #### EnumerateEdgeTpuInternal 2, count:0
libedgetpu/tflite/edgetpu_manager_direct.cc:284 #### EnumerateEdgeTpuInternal 4
available_tpus.size: 0
2
libedgetpu/tflite/edgetpu_manager_direct.cc:242 #### EnumerateEdgeTpuInternal 1
libedgetpu/driver/driver_factory.cc:130 #### DriverFactory::GetOrCreate 1
libedgetpu/tflite/edgetpu_manager_direct.cc:250 #### EnumerateEdgeTpuInternal 2
libedgetpu/driver/driver_factory.cc:48 #### DriverFactory::Enumerate 1
libedgetpu/driver/driver_factory.cc:58 #### DriverFactory::Enumerate device_list.size:0
libedgetpu/tflite/edgetpu_manager_direct.cc:252 #### EnumerateEdgeTpuInternal 2, count:0
libedgetpu/tflite/edgetpu_manager_direct.cc:284 #### EnumerateEdgeTpuInternal 4
3
INFO: Initialized TensorFlow Lite runtime.
3.1
3.2
3.3
ERROR: Failed to retrieve TPU context.
ERROR: Node number 0 (edgetpu-custom-op) failed to prepare.
Failed to allocate tensors.
Done
Here is my main.cc
#include <iostream>
#include <memory>
#include "edgetpu.h"
#include "tensorflow/lite/builtin_op_data.h"
#include "tensorflow/lite/interpreter.h"
#include "tensorflow/lite/interpreter.h"
#include "tensorflow/lite/kernels/register.h"
#include "tensorflow/lite/model.h"
namespace {
std::unique_ptr<tflite::Interpreter> BuildEdgeTpuInterpreter(
const tflite::FlatBufferModel& model,
edgetpu::EdgeTpuContext* edgetpu_context)
{
tflite::ops::builtin::BuiltinOpResolver resolver;
resolver.AddCustom(edgetpu::kCustomOp, edgetpu::RegisterCustomOp());
std::unique_ptr<tflite::Interpreter> interpreter;
if (tflite::InterpreterBuilder(model, resolver)(&interpreter) != kTfLiteOk) {
std::cerr << "Failed to build interpreter." << std::endl;
}
std::cout << "3.1\n";
// Bind given context with interpreter.
interpreter->SetExternalContext(kTfLiteEdgeTpuContext, edgetpu_context);
std::cout << "3.2\n";
interpreter->SetNumThreads(1);
std::cout << "3.3\n";
if (interpreter->AllocateTensors() != kTfLiteOk) {
std::cerr << "Failed to allocate tensors." << std::endl;
}
return interpreter;
}
}//namespace
int main(int argc, char**argv)
{
const std::string model_path = "/tmp/mobilenet_v1_1.0_224_quant_edgetpu.tflite";
std::cout << "1...\n";
std::unique_ptr<tflite::FlatBufferModel> model =
tflite::FlatBufferModel::BuildFromFile(model_path.c_str());
const auto& available_tpus = edgetpu::EdgeTpuManager::GetSingleton()->EnumerateEdgeTpu();
std::cout << "available_tpus.size: " << available_tpus.size() << "\n"; // hopefully we'll see 1 here
std::cout << "2\n";
std::shared_ptr<edgetpu::EdgeTpuContext> edgetpu_context =
edgetpu::EdgeTpuManager::GetSingleton()->OpenDevice();
std::cout << "3\n";
std::unique_ptr<tflite::Interpreter> model_interpreter =
BuildEdgeTpuInterpreter(*model, edgetpu_context.get());
std::cout << "Done\n";
return 0;
}
Now I didn't use the bazel build, but made my own CMakeLists.txt.
#mkdir buildPi
#cd buildPi
#cmake -DCMAKE_TOOLCHAIN_FILE=/home/dev/oosman/pi/Toolchain-RaspberryPi.cmake ../
#make VERBOSE=1 -j8
#https://www.pyimagesearch.com/2019/04/22/getting-started-with-google-corals-tpu-usb-accelerator/
#on raspi0: sudo apt-get install python3-edgetpu
#https://coral.ai/models/
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
set(PROJ minimal)
PROJECT(${PROJ})
set(CMAKE_C_FLAGS "-Wall -pthread")
set(CMAKE_C_FLAGS_DEBUG "-g -O0")
set(CMAKE_C_FLAGS_RELEASE "-O3")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++14 -lstdc++") #c++17 does not work with absl
set(CMAKE_CXX_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
set(CMAKE_CXX_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE})
set(CMAKE_BUILD_TYPE Debug)
set(TFLITE_ENABLE_XNNPACK OFF)
set(CMAKE_SYSTEM_PROCESSOR "armv6")
set(TENSORFLOW_DIR "${CMAKE_SOURCE_DIR}/../tensorflow")
add_definitions(-DDARWINN_PORT_USE_EXTERNAL=1)
include_directories(
${CMAKE_SOURCE_DIR}/
${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/bazel-build
${TENSORFLOW_DIR}/
${TENSORFLOW_DIR}/tensorflow/
${TENSORFLOW_DIR}/tensorflow/lite/
${TENSORFLOW_DIR}/tensorflow/lite/tools/optimize/
${CMAKE_BINARY_DIR}/tensorflow/src/tf/
${CMAKE_BINARY_DIR}/tensorflow/src/tf/tensorflow/lite/tools/make/downloads/flatbuffers/include/
${CMAKE_SOURCE_DIR}/googletest/googletest/include
${CMAKE_SOURCE_DIR}/googletest/googlemock/include
${CMAKE_BINARY_DIR}/glog_install/include
)
link_directories(
${CMAKE_BINARY_DIR}
${CMAKE_SOURCE_DIR}/../libusb/buildpi
/home/dev/oosman/pi/x-tools/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot/usr/lib/
)
add_subdirectory(tensorflow/tensorflow/lite)
add_library(edgetpu
./api/allocated_buffer.cc
./api/layer_information.cc
./api/tensor_util.cc
./api/driver_factory.cc
./api/buffer.cc
./api/driver_options_helper.cc
./api/watchdog.cc
./driver_shared/time_stamper/driver_time_stamper.cc
./tflite/custom_op_user_data_direct.cc
./tflite/custom_op_data.cc
./tflite/edgetpu_manager_direct.cc
./tflite/edgetpu_c.cc
./tflite/edgetpu_delegate_for_custom_op.cc
./tflite/edgetpu_context_direct.cc
./tflite/custom_op_direct.cc
./tflite/edgetpu_context_factory.cc
./tflite/custom_op.cc
./tflite/edgetpu_delegate_for_custom_op_tflite_plugin.cc
./driver/mmio_driver.cc
./driver/memory/mmio_address_space.cc
./driver/memory/dual_address_space.cc
./driver/memory/buddy_allocator.cc
./driver/memory/mmu_mapper.cc
./driver/memory/buddy_address_space.cc
# ./driver/memory/fake_dram_allocator.cc
# ./driver/memory/fake_mmu_mapper.cc
./driver/memory/nop_address_space.cc
./driver/request.cc
./driver/instruction_buffers.cc
./driver/mmio/coherent_allocator.cc
./driver/device_buffer.cc
./driver/executable_util.cc
./driver/aligned_allocator.cc
./driver/registers/socket_registers.cc
./driver/registers/registers.cc
./driver/package_verifier.cc
./driver/beagle/beagle_top_level_handler.cc
./driver/beagle/beagle_pci_driver_provider.cc
./driver/beagle/beagle_pci_driver_provider_linux.cc
# ./driver/beagle/beagle_pci_driver_provider_windows.cc
./driver/beagle/beagle_usb_driver_provider.cc
./driver/beagle/beagle_kernel_top_level_handler.cc
./driver/beagle/beagle_top_level_interrupt_manager.cc
./driver/kernel/kernel_interrupt_handler.cc
./driver/kernel/kernel_mmu_mapper.cc
./driver/kernel/kernel_coherent_allocator.cc
./driver/kernel/kernel_registers.cc
./driver/kernel/kernel_event_handler.cc
# ./driver/kernel/windows/kernel_event_handler_windows.cc
# ./driver/kernel/windows/kernel_registers_windows.cc
# ./driver/kernel/windows/kernel_event_windows.cc
# ./driver/kernel/windows/kernel_coherent_allocator_windows.cc
./driver/kernel/kernel_wire_interrupt_handler.cc
./driver/kernel/linux/kernel_registers_linux.cc
./driver/kernel/linux/kernel_event_linux.cc
./driver/kernel/linux/kernel_event_handler_linux.cc
./driver/kernel/linux/kernel_coherent_allocator_linux.cc
./driver/interrupt/interrupt_controller.cc
./driver/interrupt/top_level_interrupt_manager.cc
./driver/interrupt/wire_interrupt_handler.cc
./driver/interrupt/grouped_interrupt_controller.cc
./driver/dma_info.cc
./driver/driver_factory.cc
./driver/single_queue_dma_scheduler.cc
./driver/scalar_core_controller.cc
./driver/dma_info_extractor.cc
./driver/single_tpu_request.cc
./driver/device_buffer_mapper.cc
./driver/driver_factory_default.cc
./driver/run_controller.cc
./driver/driver.cc
## ./driver/driver_helper.cc
./driver/dma_chunker.cc
./driver/package_registry.cc
./driver/usb/usb_io_request.cc
./driver/usb/libusb_options_default.cc
# ./driver/usb/libusb_options_windows.cc
./driver/usb/local_usb_device.cc
./driver/usb/usb_dfu_commands.cc
./driver/usb/usb_standard_commands.cc
./driver/usb/usb_driver.cc
./driver/usb/usb_dfu_util.cc
./driver/usb/usb_registers.cc
./driver/usb/usb_ml_commands.cc
./driver/driver_factory_darwin.cc
./driver/allocator.cc
./driver/real_time_dma_scheduler.cc
# ./driver/driver_factory_windows.cc
# ./port/fileio_windows.cc
./port/timer_darwin.cc
# ./port/timer_windows.cc
./port/posix_time.cc
./port/blocking_counter.cc
./port/shared_mutex.cc
./port/default/status_macros.cc
## ./port/default/builddata.cc
./port/default/port_from_tf/status.cc
./port/default/port_from_tf/statusor.cc
./port/default/port_from_tf/logging.cc
./port/default/stringprintf.cc
./port/timer_linux.cc
)
target_link_libraries(edgetpu
tensorflow-lite
)
add_executable(minimal
main.cc
)
target_link_libraries(minimal
dl
edgetpu
tensorflow-lite
usb
udev
)
I noticed that it calls into
provider->Enumerate();
which is a pure virtual function. Two subclasses exist but none of their Enumerate methods are getting called:
BeagleUsbDriverProvider::Enumerate()
BeaglePciDriverProvider::Enumerate()
I believe BeagleUsbDriverProvider::Enumerate() should get called. But then there is nothing instantiating a BeagleUsbDriverProvider object.
What am I missing here?

I figured out the answer, it was pretty stupid, the library has to be built as a shared library:
add_library(edgetpu SHARED
...
After that I got some linker errors and fixed them by adding the paths of so files, and it worked!

Related

Can't run OpenCV-App because of runtime error missing Qt5OpenGL.dll and Qt5Test.dll

I want to build an application using the OpenCV library built with cmake.
First I downloaded the sources for opencv4.5.5. I created in that folder a subfolder mingwbuild and from there I can the command "cmake ../ -G "MinGW Makefiles"
Then I ran the command "mingw32-make install" and it took 2 hours to compile.
I then used cmake again to build a project, like described in the first answer here:
Configuring an c++ OpenCV project with Cmake
When I then ran the generated .exe, it would give me a runtime error "Qt5OpenGl.dll and Qt5Test.dll could not be found"
So I downloaded QtOpenGl.dll with MSYS2 from here https://packages.msys2.org/package/mingw-w64-x86_64-qt5-base
with the command "pacman -S mingw-w64-x86_64-qt5-base"
When I then run my opencvtest.exe , it says that it could not find the entry point of some method in QtOpenGl.dll . So the version or something must be wrong?
When searching for the package in the MSYS2 terminal, it says there are 10 packages I can download and install. The first four are:
$ pacman -Ss qt5-base
mingw32/mingw-w64-i686-qt5-base 5.15.3+kde+r174-2 (mingw-w64-i686-qt5)
A cross-platform application and UI framework (mingw-w64)
mingw32/mingw-w64-i686-qt5-base-debug 5.15.3+kde+r174-2 (mingw-w64-i686-qt5-debug)
A cross-platform application and UI framework (mingw-w64)
mingw64/mingw-w64-x86_64-qt5-base 5.15.3+kde+r174-2 (mingw-w64-x86_64-qt5) [installed]
A cross-platform application and UI framework (mingw-w64)
mingw64/mingw-w64-x86_64-qt5-base-debug 5.15.3+kde+r174-2 (mingw-w64-x86_64-qt5-debug)
Maybe if I choose the release package, I also have to set the option -DCMAKE_BUILD_TYPE=Release when invoking cmake?
Option x86 means 64-bit package and without x86, it means 32-bit packages. How can I figure out which of these I do need?
Any help is appreciated.
I finally managed to compile my OpenCVApp
The key was to work only in the MSYS2 MinGW x64 shell.
First I needed to install cmake like so:
pacman -S mingw-w64-x86_64-cmake
Then I had to install opencv with pacman like so:
pacman -S /mingw-w64-x86_64-opencv
The Qt5, I had to install like so:
pacman -S mingw-w64-x86_64-qt5-base
Then I created a new directory with src/main.cpp and CMakeLists.txt inside it like so:
Here CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
PROJECT (opencvtest)
find_package(OpenCV REQUIRED )
set( NAME_SRC
src/main.cpp
)
set( NAME_HEADERS
include/header.h
)
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/include )
link_directories( ${CMAKE_BINARY_DIR}/bin)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
add_executable( opencvtest ${NAME_SRC} ${NAME_HEADERS} )
target_link_libraries( opencvtest ${OpenCV_LIBS} )
Here main.cpp
#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
const cv::Vec3b color_azure{ 255, 129, 0 };
const cv::Vec3b color_violet{ 255, 0, 127 };
const cv::Vec3b color_black {0,0,0};
int main() {
cout << "App started" << endl;
cv::Mat image = cv::Mat(cv::Size(800, 600), CV_8UC3, color_black);
std::vector<cv::Point> vs(5);
vs[0] = cv::Point(200, 450);
vs[1] = cv::Point(600, 250);
vs[2] = cv::Point(400, 50);
vs[3] = cv::Point(200, 250);
vs[4] = cv::Point(600, 450);
std::vector<int> nk(9);
nk[0] = 0;
nk[1] = 1;
nk[2] = 2;
nk[3] = 3;
nk[4] = 4;
nk[5] = 0;
nk[6] = 3;
nk[7] = 1;
nk[8] = 4;
std::stringstream ss("Das-ist-das-Haus-vom-Ni-ko-laus");
std::vector<std::string> silben(9);
int j = 0;
while (ss.good())
{
std::string substr;
getline(ss, substr, '-');
silben[j++] = substr + "-";
}
for (int i = 0; i < 8; i++) {
cv::line(image, vs[nk[i]], vs[nk[i + 1]], color_azure, 5);
cv::putText(image, silben[i], cv::Point(i*60, 475),
cv::FONT_HERSHEY_PLAIN, 1, color_violet, 2);
cv::imshow("Image", image);
cv::waitKey();
}
cv::imshow("Image", image);
cv::waitKey(0);
return 0;
}
Then compiling and running worked fine:
mkdir buildmingw
cd buildmingw
cmake .. -G "MinGW Makefiles"
mingw32-make
bin/opencvtest.exe

How to detect hardware type (ESP32 or ESP8266) in MicroPython?

How can I detect if my MicroPython script is running on ESP32 or ESP8266?
I want to make it work on both platforms, but deep sleep requires different implementation depending on the hardware.
You can use uos.uname().sysname to detect the hardware platform.
Here is an example script:
import uos
print(uos.uname())
sysname = uos.uname().sysname
if sysname == 'esp32':
print('detected ESP32')
elif sysname == 'esp8266':
print('detected ESP8266')
else:
print('something else')
Demo script output on ESP8266:
$ ampy run detect.py
(sysname='esp8266', nodename='esp8266', release='2.2.0-dev(9422289)', version='v1.11-8-g48dcbbe60 on 2019-05-29', machine='ESP module with ESP8266')
detected ESP8266
Demo script output on ESP32:
$ ampy run detect.py
(sysname='esp32', nodename='esp32', release='1.11.0', version='v1.11 on 2019-05-29', machine='ESP32 module with ESP32')
detected ESP32

Linking to statically compiled z3 needs additional libraries on Linux

I used CMake to compile a static version of (a fairly recent of) z3 using:
cmake -DBUILD_LIBZ3_SHARED=false -DCMAKE_INSTALL_PREFIX=/opt/z3-devel -G "Unix Makefiles" ../
Now when I statically link the library against a C++ program, say this small variation of a z3 example:
#include"z3++.h"
using namespace z3;
int main(int argc, char** argv) {
config conf;
context c(conf);
expr x = c.int_const("x");
expr y = c.int_const("y");
expr z = c.int_const("z");
goal g(c);
g.add( ((2*x)+y)+z == 4);
g.add( (x+(2*y))+z == 4);
g.add( x+y == 4);
std::cout << g << "\n";
tactic t(c, "fm");
apply_result r = t(g);
std::cout << r << "\n";
return 0;
}
via
g++ -c -I /opt/z3-devel/include -static -o main.o main.cc
g++ -static -L /opt/z3-devel/lib64 -o main main.o -lz3
I receive a long list of undefined reference linking errors. What solves the issue is to add -lgomp -pthread -lrt -ldl as additional libraries. The linker outputs the following warning:
/usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/8/libgomp.a(target.o): in function `gomp_target_init':
(.text+0x32c): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
Nevertheless, the program runs fine on my own machine and on Starexec.
Is this combination of static and dynamic linking the best I can do? Shouldn't those libraries be already statically linked into libz3.a? I have static versions of gomp, pthread and rt available on the system.

Error in compiling using gsoap

I am trying to compile the files after generating from these steps:-
(1) wsdl2h -o calc.h http://www.genivia.com/calc.wsdl
(2) soapcpp2 -j -CL calc.h
(3) Creating a main.cpp with the following code:-
#include "calc.nsmap" // XML namespace mapping table (only needed once at the global level)
#include "soapcalcProxy.h" // the proxy class, also #includes "soapH.h" and "soapStub.h"
int main()
{
calcProxy calc;
double sum;
if (calc.add(1.23, 4.56, sum) == SOAP_OK)
std::cout << "Sum = " << sum << std::endl;
else
calc.soap_stream_fault(std::cerr);
calc.destroy(); // same as: soap_destroy(calc.soap); soap_end(calc.soap);
}
After it I compile issuing the command:-
g++ -o calcclient main.cpp soapcalcProxy.cpp soapC.cpp -lgsoap++
I get the following errors:-
/tmp/ccA5Ergj.o: In function `soap_ignore_element(soap*)':
soapC.cpp:(.text+0x112d): undefined reference to `soap_ignore'
/tmp/ccA5Ergj.o: In function `soap_putelement':
soapC.cpp:(.text+0x149b): undefined reference to `soap_element_empty'
collect2: error: ld returned 1 exit status
Please help in compiling.
I solved this. I was thinking the lib is in /usr/lib but it was in /usr/local/lib. I included -L/usr/local/lib while compiling, and it worked.

Cannot grab image from Xtion Pro Live with Opencv code

I am using OpenCV 2.4.10 and I want to take image from my Asus Xtion Pro Live. When I'm trying to execute the code below, I get this error: "Can not open capture."
I tried everything, like Sensor update, opencv with openni compiling and opencv re-installing (even the version 2.4.6).
OpenNI and Sensor are working properly since I am able to run examples such as NiViewer. But the example openni_capture.cpp (on opencv-2.4.10/samples/cpp) cannot run properly.
The code:
#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char* argv[])
{
VideoCapture capture;
capture.open(CV_CAP_OPENNI_ASUS);
if ( !capture.isOpened() )
{
cout << "Error opening capture" << endl;
return -1;
}
if( !capture.grab() )
{
cout << "Can not grab image" << endl;
}
return 0;
}
The compiling is done with the following command:
g++ capture.cpp -o capture pkg-config --cflags opencv --libs opencv
How can i fix this error? Is there any problem with the opencv version that i use?
I did what is being said on Can not grab image from VideoCapture OpenCV with Asus Xtion Pro Live
but the problem still exists.
What serial ports are listed when you print out the list as you're doing ? Have you checked to see what serial port your camera is connected to ? On Linux you can list mounted devices with :
lsusb

Resources