OpenCV how to select which camera to connect to? - linux

I am writing an OpenCV 3.4 app on Ubuntu 16.04.
However, I am running into a problem where no matter what deviceId I set on my VideoCapture() function, I always get the built in webcam stream. However I need to get the stream from my usb camera. Btw my usb camera is a Logitech c920, and my computer is a ThinkPad P51 (not sure if that would matter)
Here is my code:
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/aruco.hpp>
#include <iostream>
int main(int, char**){
cv::Mat inputImage;
std::vector<int> markerIds;
std::vector<std::vector<cv::Point2f> > markerCorners, rejectedCandidates;
cv::aruco::DetectorParameters parameters;
cv::VideoCapture inputVideo(1); // I have tried 0, 1, 2...20 all the same stream
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_50);
while (inputVideo.grab()){
cv::Mat image, imageCopy;
inputVideo.retrieve(image);
image.copyTo(imageCopy);
std::vector<int> ids;
std::vector<std::vector<cv::Point2f> > corners;
cv::aruco::detectMarkers(image, dictionary, corners, ids);
if (ids.size() > 0) cv::aruco::drawDetectedMarkers(imageCopy, corners, ids);
cv::imshow("out", imageCopy);
if(cv::waitKey(30) >= 0) break;
}
}
Thanks!
EDIT:
This is the result I get with ls -lR /dev/v4l:
/dev/v4l:
total 0
drwxr-xr-x 2 root root 80 Feb 23 10:53 by-id
drwxr-xr-x 2 root root 80 Feb 23 10:53 by-path
/dev/v4l/by-id:
total 0
lrwxrwxrwx 1 root root 12 Feb 23 10:53 usb-046d_HD_Pro_Webcam_C920_25CCF0FF-video-index0 -> ../../video1
lrwxrwxrwx 1 root root 12 Feb 23 2019 usb-8SSC20F27019L1GZ83C07ZY_Integrated_Camera-video-index0 -> ../../video0
/dev/v4l/by-path:
total 0
lrwxrwxrwx 1 root root 12 Feb 23 10:53 pci-0000:00:14.0-usb-0:6:1.0-video-index0 -> ../../video1
lrwxrwxrwx 1 root root 12 Feb 23 2019 pci-0000:00:14.0-usb-0:8:1.0-video-index0 -> ../../video0
And this is what I get with lsusb:
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 005: ID 138a:0097 Validity Sensors, Inc.
Bus 001 Device 004: ID 04ca:7066 Lite-On Technology Corp.
Bus 001 Device 008: ID 046d:082d Logitech, Inc. HD Pro Webcam C920
Bus 001 Device 003: ID 046d:c539 Logitech, Inc.
Bus 001 Device 002: ID 04d9:0169 Holtek Semiconductor, Inc.
Bus 001 Device 006: ID 8087:0a2b Intel Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Not sure how to match them?

Related

org.bluez.error.inprogress error with bluetooth

I have an issue where the Bluetooth got disconnected after 1-2s of connection, the master side will show the following error:
org.bluez.error.inprogress
tracing to the log I saw it will enter the following func:
un 11 16:23:46 rap bluetoothd[21474]: src/device.c:search_cb() 00:0E:8E:8B:CA:9D: No service update
Jun 11 16:23:46 rap bluetoothd[21474]: src/device.c:device_svc_resolved() /org/bluez/hci0/dev_00_0E_8E_8B_CA_9D err 0
Jun 11 16:23:46 rap bluetoothd[21474]: src/device.c:connect_profiles() /org/bluez/hci0/dev_00_0E_8E_8B_CA_9D (all), client :1.394
...
Jun 11 16:23:49 rap kernel: [12110.003903] bluetooth:l2cap_sock_release:1197: sock 0000000078f38a7c, sk 00000000f306c001
Jun 11 16:23:49 rap kernel: [12110.003907] bluetooth:l2cap_sock_shutdown:1113: sock 0000000078f38a7c, sk 00000000f306c001
Jun 11 16:23:49 rap kernel: [12110.003910] bluetooth:l2cap_sock_shutdown:1123: Handling sock shutdown
Jun 11 16:23:49 rap kernel: [12110.003913] bluetooth:l2cap_chan_hold:489: chan 0000000093211dd1 orig refcnt 3
Jun 11 16:23:49 rap kernel: [12110.003916] bluetooth:l2cap_sock_shutdown:1132: chan 0000000093211dd1 state BT_CONNECTED
Jun 11 16:23:49 rap kernel: [12110.003921] bluetooth:l2cap_chan_close:732: chan 0000000093211dd1 state BT_CONNECTED
Jun 11 16:23:49 rap kernel: [12110.003924] bluetooth:l2cap_chan_hold:489: chan 0000000093211dd1 orig refcnt 4
Jun 11 16:23:49 rap kernel: [12110.003930] bluetooth:l2cap_build_cmd:2931: conn 000000003e9a2ca4, code 0x06, ident 0x05, len 4
Jun 11 16:23:49 rap kernel: [12110.003936] bluetooth:l2cap_send_cmd:865: code 0x06
and tracing to the code in blueZ:
static DBusMessage *connect_profiles(struct btd_device *dev, uint8_t bdaddr_type,
DBusMessage *msg, const char *uuid)
{
struct bearer_state *state = get_state(dev, bdaddr_type);
int err;
DBG("%s %s, client %s", dev->path, uuid ? uuid : "(all)",
dbus_message_get_sender(msg));
if (dev->pending || dev->connect || dev->browse)
return btd_error_in_progress(msg); <------------------ HERE
...
}
My question can I somehow know which condition (pending/connect/browse) is causing this error without adding editing the code as I dont have permission to do that ? and how come the blueZ will try to connect to the profile if any of this condition is in progress?
Try restarting the bluetooth service. Had an error that said the same and managed to solve it by restarting the bluetooth service.
sudo service restart bluetooth
Try running the above command and see if it helps.

How to configure unknown usb device as ethernet on Linux host?

When my USB device was connected, I got the following:
$ dmesg | tail
[ 79.612133] usb 2-2: new full-speed USB device number 3 using ohci-pci
[ 79.937340] usb 2-2: New USB device found, idVendor=238b, idProduct=0a21
[ 79.937343] usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 79.937344] usb 2-2: Product: DMR Radio
[ 79.937346] usb 2-2: Manufacturer: Hytera Communications
[ 80.282770] cfg80211: Loading compiled-in X.509 certificates for regulatory database
[ 80.286007] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
[ 80.399206] usbcore: registered new interface driver cdc_ether
[ 80.404402] usbcore: registered new interface driver rndis_host
[ 80.421516] usbcore: registered new interface driver rndis_wlan
There is no message like "cdc_subset 1-4.4.2:1.1: usb0: register 'cdc_subset' at usb-0000:00:02.1-4.4.2, Linux Device".
So there is no ethernet named as usb0.
$ uname -a
Linux VB1804 4.15.0-36-generic #39-Ubuntu SMP Mon Sep 24 16:19:09 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
It is shown as unknown device.
$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 003: ID 238b:0a21
Bus 002 Device 002: ID 80ee:0021 VirtualBox USB Tablet
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
$ lsmod | grep usbnet
usbnet 45056 3 rndis_host,cdc_ether,rndis_wlan
mii 16384 1 usbnet
I got the same on physical Linux.
And,
$ usb-devices
--------- other usb devices ----
T: Bus=02 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 3 Spd=12 MxCh= 0
D: Ver= 2.00 Cls=ff(vend.) Sub=fe Prot=fe MxPS= 8 #Cfgs= 1
P: Vendor=238b ProdID=0a21 Rev=00.00
S: Manufacturer=Hytera Communications
S: Product=DMR Radio
C: #Ifs= 3 Cfg#= 1 Atr=c0 MxPwr=4mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=02 Prot=ff Driver=(none)
I: If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=(none)
I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
I add the idVendor and idProduct to the white list of structure array prodocts[] in file rndis_host.c.
static const struct usb_device_id products [] = {
{ /* DMR Radio*/
USB_DEVICE_AND_INTERFACE_INFO(0x238b, 0x0a21,
USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
.driver_info = (unsigned long) &rndis_info,
}, {
And, It works.

FTDI D2XX FT_DEVICE_LIST_INFO_NODE structure is all zeros

I am trying to get a Matlab MEX to run in Linux. It uses FTDI's D2XX library v1.3.6 (Documentation).
FT_CreateDeviceInfoList(&ftdi_count) gives me an ftdi_count of 1, so the FTDI chip is detected.
However, when iterating through the device list from FT_GetDeviceInfoList(device_list, &ftdi_count), my FT_DEVICE_LIST_INFO_NODE structure is all zeros, so obviously the code cannot find the device with the description it is looking for:
(gdb) p *p_device
$3 = {Flags = 1, Type = 3, ID = 0, LocId = 0, SerialNumber = '\000' <repeats 15 times>,
Description = '\000' <repeats 63 times>, ftHandle = 0x0}
My first guess was that udev wasn't set up. But the problem persists with
SUBSYSTEM=="usb", ATTR{idVendor}=="0403", ATTR{idProduct}="6014", MODE="0666"
lsusb -v has access to the values:
Bus 001 Device 012: ID 0403:6014 Future Technology Devices International, Ltd FT232H Single HS USB-UART/FIFO IC
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0403 Future Technology Devices International, Ltd
idProduct 0x6014 FT232H Single HS USB-UART/FIFO IC
bcdDevice 9.00
iManufacturer 1 FTDI
iProduct 2 [company that provided me with their] Kit v3
iSerial 3 FT266WVA
bNumConfigurations 1
[...]
What can I do to make the FTDI functions work?
The problem is that Linux automatically loads the VCP driver (ftdi_sio).
In the Question How can I get Linux device with FTDI D2XX driver API, Akira shows a udev script to from A blog unload that driver. I modified it to work with my FT232H chip, which has only one port:
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", RUN+="/bin/sh -c 'echo -n $kernel:1.0 > /sys/bus/usb/drivers/ftdi_sio/unbind;'"

How to use alsa sound and/or snd_pcm_open in docker?

I am running an Ubuntu 12.04 Docker container on an Ubuntu 16.04 host. Some test code I have exercises 'snd_pcm_open'/'snd_pcm_close' operations with the SND_PCM_STREAM_PLAYBACK and SND_PCM_STREAM_CAPTURE stream types.
I do not need any actual sound/audio capabilities but just getting the 'snd_pcm_open' return 0 with a valid handle, then 'snd_pcm_close' to return 0 on the same handle would be good enough for my purposes. I do not want to modify the code as it's already got some not-so-nice platform dependent switches and I am not the maintainer.
I am using the simple code and compiling it as 'g++ alsa_test.cpp -lasound'
#include <stdio.h>
#include <alsa/asoundlib.h>
int main() {
snd_pcm_t* handle;
snd_pcm_stream_t stream_type[]= {SND_PCM_STREAM_PLAYBACK, SND_PCM_STREAM_CAPTURE};
printf("\nstarting\n");
for (unsigned char i = 0; i < sizeof(stream_type) / sizeof(stream_type[0]); ++i) {
printf(">>>>>>>>\n\n");
int deviceResult = snd_pcm_open(&handle, "default" , stream_type[i], 0);
printf("\n%d open: %d\n", stream_type[i], deviceResult);
if (deviceResult >= 0) {
printf("attempting to close %d\n", stream_type[i]);
snd_pcm_drain(handle);
deviceResult = snd_pcm_close(handle);
printf("%d close: %d\n\n", stream_type[i], deviceResult);
}
printf("<<<<<<<<\n\n");
}
return 0;
}
It works just fine on the host but despite all the different things I tried, 'snd_pcm_open' returns '-2' for both stream types in the container.
I tried installing the 'libasound2.dev' but 'modinfo soundcore' is empty and '/dev/snd' does not exist.
Also tried running the container with the options below, even though it feels like a massive over kill for such a simple purpose
--privileged --cap-add=ALL -v /dev:/dev -v /lib/modules:/lib/modules
After these extra parameters to the container, following commands generate the same output both in the host and the container.
root#31142791f82d:/export# modinfo soundcore
filename: /lib/modules/4.4.0-59-generic/kernel/sound/soundcore.ko
alias: char-major-14-*
license: GPL
author: Alan Cox
description: Core sound module
srcversion: C941364F5CD0B525693B243
depends:
intree: Y
vermagic: 4.4.0-59-generic SMP mod_unload modversions
parm: preclaim_oss:int
root#31142791f82d:/export# ls -l /dev/snd/
total 0
drwxr-xr-x 2 root root 100 Feb 2 21:10 by-path
crw-rw----+ 1 root audio 116, 2 Feb 2 07:42 controlC0
crw-rw----+ 1 root audio 116, 7 Feb 2 07:42 controlC1
crw-rw----+ 1 root audio 116, 12 Feb 2 21:10 controlC2
crw-rw----+ 1 root audio 116, 6 Feb 2 07:42 hwC0D0
crw-rw----+ 1 root audio 116, 11 Feb 2 07:42 hwC1D0
crw-rw----+ 1 root audio 116, 3 Feb 2 07:42 pcmC0D3p
crw-rw----+ 1 root audio 116, 4 Feb 2 07:42 pcmC0D7p
crw-rw----+ 1 root audio 116, 5 Feb 2 07:42 pcmC0D8p
crw-rw----+ 1 root audio 116, 9 Feb 2 10:44 pcmC1D0c
crw-rw----+ 1 root audio 116, 8 Feb 2 07:42 pcmC1D0p
crw-rw----+ 1 root audio 116, 10 Feb 2 21:30 pcmC1D1p
crw-rw----+ 1 root audio 116, 14 Feb 2 21:10 pcmC2D0c
crw-rw----+ 1 root audio 116, 13 Feb 2 21:10 pcmC2D0p
crw-rw----+ 1 root audio 116, 1 Feb 2 07:42 seq
crw-rw----+ 1 root audio 116, 33 Feb 2 07:42 timer
The container only has the 'root' user by the way, so, access rights shouldn't be an issue either.
What would be the easiest and least hacky way to get this working? I'd rather get rid off the privileged mode and dev/modules mapping to the container however, these containers are not accessed from the outside world and are only created/destroyed for some short lived tasks. So, safety isn't exactly a massive concern.
Thanks in advance.
If you don't actually need the device to work correctly, use the null device instead of default.
To make the null plugin the default one, put this into the container's /etc/asound.conf, or into the user's ~/.asoundrc:
pcm.!default = null;

Issue saving a cvs file to a usb drive using node on a raspberry pi

This one is really doing my head in! please help!
So I have a little raspberry pi 2 running debian and node 0.12.6.
The node script listens to a home automation bus for events and saves these to a json list. This list is then saved to cvs using a cron job hourly (every min for testing) to a usb drive that is mounted at boot on the system.
The issue is that every time fs.writeFile is called it throws an error.
This only happens if I try and save to the usb drive, and not to local folders, which work fine.
I have altered the /etc/fstab file to include the following
/dev/sda1 /home/pi/knx/usb vfat user,auto,nodev,gid=pi,uid=pi,fmask=0111,dmask=0000 0 0
This appears to mount the usb at boot and I can as pi user make dirs and files no problem from the console.
The permissions of the folder (with the usb drive mounted at usb) look like this....
pi#raspberrypi ~/knx $ ls -l
total 24
-rw-r--r-- 1 pi pi 965 Nov 20 16:40 app.js
drwxr-xr-x 2 pi pi 4096 Nov 20 16:00 data_files
drwxr-xr-x 2 pi pi 4096 Nov 19 12:27 install_scripts
drwxr-xr-x 7 pi pi 4096 Nov 20 16:21 node_modules
drwxrwxrwx 8 pi pi 8192 Jan 1 1970 usb
The drive looks to be mounted ok....
pi#raspberrypi ~/knx $ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 1 15G 0 disk
└─sda1 8:1 1 15G 0 part /home/pi/knx/usb
The node script is ...
//set up chron job to save list
var job = new CronJob({
cronTime: '00 0-59 * * * *',
onTick: function() {
console.log('saving file');
json2csv({ data: listToSave, fields: fields }, function(err, csv) {
if (err) console.log(err);
tempfilename = new Date();
fname = './usb/data_files/'+ tempfilename.toString() +'.csv';
console.log(fname);
fs.writeFile(fname, csv, function(err) {
if (err) throw err;
console.log('file saved');
listToSave=[];
});
});
},
start: true,
});
The fname looks like this....
'./usb/data_files/Fri Nov 20 2015 16:42:00 GMT+0000 (UTC).csv'
If I had any hair - I would have well and truly pulled it out by now!
Any ideas on a solution?
It looks like the filename you are creating with "new Date()" is an invalid format for the filesystem.
I'm able to make your code work by formatting the raw date string into a friendlier file name:
var utils = require('util')
Above adds the util module for string formatting.
var today = new Date();
var fname = utils.format('./usb/%s-%s-%s.csv', today.getMonth(), today.getDay(), today.getHours());
This writes a "MM-dd.csv" filename which appears to work on my debian machine. You can extend this by adding the time, year , etc.

Resources