Using USB API (MTP) with libghoto2 and Python bindings on MacOS, Raspberry Pi, Linux, ROS

Hi, sorry for the delay. I was trying to get more progress before I updated the group here. Unfortunately, I still don’t have libgphoto2 working properly with Python bindings.

Currently, list-files.py does work for me, but I get the same WARNING at the top as you. I would like to eliminate the warning. The output does work, but it is not satisfying.

When I used mhenrie’s program, I have a different error. I get the ‘Unable to copy DNG’ error raised by this section.

        gp_dng_path = wait_for_event(self.camera, timeout=TIMEOUT_CAPTURE_DNG, event_type=gp.GP_EVENT_FILE_ADDED)
        if not gp_dng_path:
            raise RuntimeError('Unable to copy DNG')

Thus, the command line program gphoto2 works for me, but the Python bindings in libgphoto2 do not work.

At the moment, I am using ptpcam from libptp2 inside of programs by running running a shell process inside of my program. As the API commands are not time sensitive, this seems to work, but is not satisfying.

The C functions inside of libptp are not that friendly to use, so I would like to use libghoto2, but I’m not sure if the full library of API commands work with the THETA.

I believe the best path forward is to use mhenrie’s program and modify the _unittest to test less features first, then apply a debugger and see what is happening to the variable dng_path

I just thought that maybe you hadn’t noticed. I’m sorry if I rushed you.

I have been wondering for a long time if it is possible to fix the error at the time of video shooting by modifying the source code of libgPhoto2.
@Hugues has suggested the possibility of resolving the error by modifying the source.
Could it be possible to fix the problem as well, so that gphoto2 --set-config movie=0 does not stop video recording?
I think I can do it.
But I can’t write it because I don’t know what the source code is, but it’s too big for me.
I should be able to figure it out by myself sooner or later.
Is it naive to wait for someone to solve the problem?

Aside from that, I had a similar error when using @mhenrie’s program.
When I saw that error, I took a peek at the shutter speed and exposure time settings that weren’t working properly and made them work.

We have many options.

  • Keep trying the libgPhoto2 system

    • We will continue to use the python-gphoto2 system, which converts C code by SWIG, with analysis and improvement.

    • Use gphoto2-cffi, which is converted by cffi
      I believe operational testing is not yet available on this forum. git, pypi

    • Another use of piggyphoto to convert with another ctype
      ‘This is a very rough proof of concept. feel free to play with it and add improvements.’
      so you might not expect it to work very well. git

  • Try the Python binding in linptp2
    I can’t find anything useful here, according to my research.
    I found a hit on git, but it’s not available on Linux because they don’t know how to compile it as a shared library.
    Does anyone know how to use it?

By the way, I’m going to move on to the next phase of operational testing.

1 Like

I have the same problem with libgphoto2. It is a big project. I have a difficult time understanding it.

I do not think anyone else will solve the problem. It may be up to you if you want the challenge. :slight_smile:

John Thomas was looking at GitHub - Parrot-Developers/sequoia-ptpy: Python library used to communicate with PTP devices like Parrot Sequoia

The last I checked, he did not have it working around 3 weeks ago. Maybe it is working now?

I understand that it is better to have working Python bindings when using ROS on Linux. However, I think that people can run shell process if they need to as a workaround.

In the discussion of that GitHub issue, you may notice a reference to a RICOH USB SDK. Note that SDK is not the SDK for the RICOH THETA. It is for other RICOH cameras.

1 Like

I don’t know if it will be usefull for you but to stop the video recording I’m using the command
gphoto2 --set-config=/main/actions/opcode=0x1018,0xFFFFFFFF

Hugues

2 Likes

I’m surprised there’s such a solution! But unfortunately, it didn’t work in my environment.
My environment is as below.

  • Ubuntu 16.04LTS
  • ThetaV 3.40.1
  • gphoto2 2.5.9
  • libgphoto2 2.5.9
  • libgphoto2_port 0.12.0

※gPhoto2 related items are all unmodified

gphoto2 --set-config=/main/actions/opcode=0x1018,0xFFFFFFFF

*** Error ***
The /main/actions/opcode widget is not configurable.
*** Error (-2: ‘Bad parameters’) ***

For debugging messages, please use the --debug option.
Debugging messages may help finding a solution to your problem.
If you intend to send any error or debug messages to the gphoto
developer mailing list gphoto-devel@lists.sourceforge.net, please run
gphoto2 as follows:

env LANG=C gphoto2 --debug --debug-logfile=my-logfile.txt --set-config=/main/actions/opcode=0x1018,0xFFFFFFFF

Please make sure there is sufficient quoting around the arguments.

First, thanks to @Hugues for providing this fix. Amazing that you could figure it out! I can’t even find the documentation for --set-config=/main/actions/opcode=

Second, for @NaokiSato102, the solution works for me. I believe that maybe you are not starting the video or your THETA is mounted as a file system?

Here is my complete test

unmount camera

If the camera is mounted, the commands may not work.

image

set to video mode

Using the API reference, we can see that video mode is hex 0x8002 or 32770 in base 10.

$ gphoto2 --set-config=5013=32770

start video

$ gphoto2 --set-config movie=1

stop video

$ gphoto2 --set-config=/main/actions/opcode=0x1018,0xFFFFFFFF

start video and stop after specified time

$ gphoto2 --set-config movie=1 --wait-event=2s --set-config movie=0 
Behavior with Audio Beep

There is a beep after each command and no errors on the console.

image

checking media

If you mount the camera again, you can see the media.

image

In my test, I have intentionally disabled internal stitching.

I suspect that your camera may be auto-mounting. Please check it and report back.

I have added this test to the USB API documentation on the Linux streaming documentation I am building. I’m providing attribution to Hugues by linking to his profile on this site along with his ID on this site.

(Missed stringing the replies together.)

I have firmly unmounted Theta and started recording and then tried it.

I would appreciate it if you all could tell me the results of your tests with information on your experimental environment.

Is it interference from other applications etc.? I do not know the reason.
I’m going to try it in the raspberry-pi environment as well.

The fact that the stop command works with --set-config suggests that it can work with the corresponding code in Python-gPhoto2. I can’t think of any code at the moment, but I think I can convert @mhenrie’s code to suit.

Also, was “gphoto2 --set-config movie=1 --wait-event=2s --set-config movie=0” able to exit after the shooting started successfully in @craig’s environment? This should have been inoperative in my perception, i.e. it was not possible to stop shooting.

RICOH THETA Z1 with firmware 1.50.1

craig@cube:~$ lsb_release -a
LSB Version:	core-11.1.0ubuntu2-noarch:security-11.1.0ubuntu2-noarch
Distributor ID:	Ubuntu
Description:	Ubuntu 20.04.1 LTS
Release:	20.04
Codename:	focal
craig@cube:~$ 

craig@cube:~$ cat /proc/cpuinfo 
processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 60
model name	: Intel(R) Pentium(R) CPU G3258 @ 3.20GHz

craig@cube:~$ gphoto2 --version
gphoto2 2.5.23

This version of gphoto2 is using the following software versions and options:
gphoto2         2.5.23         gcc, popt(m), exif, cdk, aa, jpeg, readline
libgphoto2      2.5.25         standard camlibs (SKIPPING lumix), gcc, ltdl, EXIF
libgphoto2_port 0.12.0         iolibs: disk ptpip serial usb1 usbdiskdirect usbscsi, gcc, ltdl, EXIF, USB, serial without locking

It worked in my test. The correct video was saved to file. Note that the camera was in video mode at the start of the sequence.

Test 2 Using RICOH THETA V

Equipment

Host system is the same as described above.

Camera is

$ gphoto2 --summary
Camera summary:                                                                
Manufacturer: Ricoh Company, Ltd.
Model: RICOH THETA V
  Version: 3.40.1
  Serial Number: 00105377
Vendor Extension ID: 0x6 (1.10)

Test 2.1 - manually starting and stopping video

craig@cube:~$ gphoto2 --set-config movie=1
craig@cube:~$ gphoto2 --set-config=/main/actions/opcode=0x1018,0xFFFFFFFF
craig@cube:~$    

Result: successful


Test 2.2 - automatically stopping video

craig@cube:~$ gphoto2 --set-config movie=1 --wait-event=2s --set-config movie=0 

Result: successful

It’s interesting that there are different versions of gphoto2. It may be derived from that.

I CAN NOT get gphoto2 2.5.23 by apt install.
What should I do?

When I installed gPhoto2 using gPhoto2-updater after removing an existing apt-derived gPhoto2 with reference to this article, I was able to execute the commands which @craig presented and the configuration of gPhoto2 became the same.
It seems to be better to use gPhoto2-updater than to install it with apt.
But I wonder why gPhoto2-updater has not been updated. I wonder why we have to separate gPhoto2-updater and apt.

add 20/10/04

As usual, “gphoto2 --set-config-index shutterspeed=10” did not work properly, but the error message changed.

Previously.

*** Error (-110: 'I/O in progress') ***

Present.

*** Error ***              
Shutterspeed not found in configuration tree.
*** Error (-1: 'Unspecified error') ***

[quote=“NaokiSato102, post:39, topic:4521, full:true”]
I CAN NOT get gphoto2 2.5.23 by apt ins[/quote]

Did you modify the source code per the tip from hughes and compile it?

Thanks craig. I was already able to do it the way I did one previous post, using gPhoto2-updater. Now I’m in the same environment as you. I haven’t added any of hughes’ improvements yet, however. We’ll get to that in a while.
It’s important to analyze the gPhoto2 Python bindings, but I have a mid-term presentation exercise on 10/7 with not much progress on the multiple Theta control apps. I’ll need a progress report at that time, so I have to hurriedly create a program that reflects the results of the analysis.

Could you try out scripts/pytheta.py in the Enhance-checking-Theta branch of this repository with multiple Thetas connected?

The comments are in Japanese. The comments are in Japanese, but they are for our own use only for now. Sorry.
I’m going to add English comments to this site when I have time.

By the way, where did you get this information?

I don’t remember, it was 2 years ago. I think I found the gphoto2 pattern for opcode in a forum for another camera brand. With examples, I knew how to pass parameters using opcode operation .
With theta USB API documentation provided by Ricoh, it was easy to get most of operations working.

1 Like

I tried to start and end shooting only in gPhoto with Python binding.
It started successfully, but failed to end.
It doesn’t even show an error message, just “0x1018,0xFFFFFFFFFFFFFFFF” on the console.
I don’t know what’s going on as I don’t fully understand its use.
Can you help me out?

Below is the code we tried.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import time
import gphoto2 as gp

# milliseconds
TIMEOUT = 10

def wait_for_event(camera, timeout=TIMEOUT, event_type=gp.GP_EVENT_TIMEOUT):
	"""
	Wait for event_type to to be triggered.
	:param camera:
	:param timeout:
	:param event_type:
	:return: event_data
	"""
	while True:
		_event_type, event_data = camera.wait_for_event(timeout)
		if _event_type == gp.GP_EVENT_TIMEOUT:
			return
		if _event_type == event_type:
			return event_data

def main():
	camera = gp.Camera()
	try:
		camera_config = camera.get_config()
	except gp.GPhoto2Error:
		raise RuntimeError("Unable to connect to Camera")
	actions_config = camera_config.get_child_by_name('actions')
	movie = actions_config.get_child_by_name("movie")
	movie.set_value(1)
	camera.set_config(camera_config)
	wait_for_event(camera)
	time.sleep(5)

	opcode = actions_config.get_child_by_name("opcode")
	opcode.set_value("0x1018,0xFFFFFFFF")
	print(opcode.get_value() )

if __name__ == "__main__":
	main()

@craig! I’ve completed the video ingestion function in the multi_view_image repository I was developing!
Now you can connect multiple Theta’s, take a picture, get the remaining recording time, finish recording, and take in a video with one click!

2 Likes

This is fantastic. What version of Python and gphoto are you using?

python main.py 
[debug] check_if_theta 処理開始
[debug] [0]:[usb:003,009] [USB PTP Class Camera]
can't get debug descriptor: Resource temporarily unavailable
[debug] [b'  iProduct                2 RICOH THETA Z1\n']
[debug]シータです
[debug] check_if_thetaは正常終了
[/run/user/1000/gvfs/gphoto2:host=%5Busb%3A003%2C009%5D]はアンマウント済みです
Exception in thread usb:003,009:
Traceback (most recent call last):
  File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.8/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "/home/craig/Development/ricoh/usb/multi_view_image/scripts/pytheta.py", line 198, in inner_start_capture
    camera.set_config(camera_config)
gphoto2.GPhoto2Error: [-1] Unspecified error

...
*** Error ***              
Failed to set new configuration value 0x1018,0xFFFFFFFF for configuration entry /main/actions/opcode.
*** Error (-1: 'Unspecified error') ***       

Exception in thread usb:003,009:
Traceback (most recent call last):
  File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.8/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "/home/craig/Development/ricoh/usb/multi_view_image/scripts/pytheta.py", line 226, in inner_finish_capture
    sp.check_output(cmd, shell=True)
  File "/usr/lib/python3.8/subprocess.py", line 411, in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
  File "/usr/lib/python3.8/subprocess.py", line 512, in run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command 'gphoto2 --set-config=/main/actions/opcode=0x1018,0xFFFFFFFF --port=usb:003,009' returned non-zero exit status 1.

Did you find out that you need to unmount gvfs?

def unmount_theta(theta_list):
	"""	
	マウントされているThetaをアンマウントする。  
	そもそもマウントしないようにすれば良いかもしれないが、  
	他の機材の使用に師匠が出うる設定が必要なのでこの実装となった。
	Parameters
	----------
	theta_list : list
		接続されているThetaのリスト
	"""
	for addr in theta_list:
		path = "/run/user/1000/gvfs/gphoto2:host=%5B"+url.quote(addr)+"%5D"
		if os.path.exists(path):
			print("[{:s}]をアンマウントします".format(path) )
			sp.check_output(["gvfs-mount", "-u", path])
			# cmd = "gvfs-mount -u /run/user/1000/gvfs/mtp:host=%5B"+url.quote(addr)+"%5D"
			# sp.check_output(cmd,shell=True) #こういう書き方もある。
		else:
			print("[{:s}]はアンマウント済みです".format(path))

the THETA Z1 is not mounted on my system.

$ gvfs-mount -l
This tool has been deprecated, use 'gio mount' instead.
See 'gio help mount' for more info.

Drive(0): Samsung SSD 860 QVO 1TB
  Type: GProxyDrive (GProxyVolumeMonitorUDisks2)
Drive(1): ST2000LM007-1R8174
  Type: GProxyDrive (GProxyVolumeMonitorUDisks2)
  Volume(0): 2.0 TB Volume
    Type: GProxyVolume (GProxyVolumeMonitorUDisks2)