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.
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!
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)
The versions of each of the related applications in this system are as follows
gphoto2 2.5.23
libgphoto2 2.5.25
libgphoto2_port 0.12.0
Python 2.7.12
Python-gphoto2 2.2.2
This system will be used in ROS, so it is assumed to run on Python 2.7.
If you are having problems with the unmount process, it may be because the mount format may be slightly different depending on whether you have gvfs-backend or not. (Specifically, the name is different when mounted.)
The unmounted part is designed to make this system work without killing gvfs-backend, so if you’re not supposed to mount it in the first place, you don’t need that part. Comment out and give it a try.
Found out why I can’t run a stop and The meaning of a function!
The reason is because I didn’t write “camera.set_config(camera_config)” after “opcode.set_value(“0x1018,0xFFFFFFFFFFFF”)”.
If you remember to write this function, you can perform the exit.
That means that camera.set_config() is meant to adapt the modified configuration to the device!
I’ll post a short piece of code below that you can easily try out.
from __future__ import print_function
import time
import gphoto2 as gp
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) # It was discovered that this function was adapting the changed settings.
time.sleep(5)
opcode = actions_config.get_child_by_name("opcode")
opcode.set_value("0x1018,0xFFFFFFFF")
camera.set_config(camera_config) # This is where I adapted the settings. This is an additional point.
print(opcode.get_value() )
if __name__ == "__main__":
main()
I hope the authors of Python-gPhoto have something like this in their sample code. I guess I should just throw a pull request for it?
Thanks for all your work and this information. I will try it out. I do not use ROS, though I have the components installed. Can you let me know a little more information about it?
- Is 16.04 the most common version? The Kinetic Kame version was released in May of 2016. Are there packages related to Kinetic Kame that are not on Melodic Morenia and Noetic Ninjemys. I’m wondering which version to use for testing. Support for Kinetic Kame is running out in April 2021. Maybe I should try Melodic Morenia on Ubuntu 18.04?
- What are you using ROS for? I’m wondering what packages I should test to get more familiar with ROS myself.
If you only want to run pytheta.py, then the ROS is irrelevant, except for the Python version.
I’m not sure which is more common in general terms. In the meantime, kinetic is close to running out of support, so new learners should avoid it unless there are very special circumstances.
And you should choose between Melodic and Noetic, if you like, for the following reasons
Melodic has more documentation, but is a bit older.
Noetic may not have as much documentation, but it is one of the most recent.
I’ll give some details about ROS versioning just in case.
My program is developed to be ROS Kinetic compatible, in order to use it in combination with the “orne_gamma” branch of the autonomous control package called “orne_navigation”.
There is also a melodic-ready branch, but the “orne_gamma” was born before the melodic-ready branch was born, so I haven’t adapted the difference yet.
And I’m not used to ROS, so I’ve been putting off applying the diffs until later.
I will continue to use kinetic for that reason.
- thank you for your contribution and information
- You’re probably busy with your research, so you do not need to reply
- I’m continuing on to try and get this to work as I feel it may be of use to other people. However, you don’t have to spend time on getting this to work on other systems unless it is of interest to you.
I’m using Python 2.7.18 on Ubuntu 20.04. This is just an FYI for you.
$ python --version
Python 2.7.18
$ python main.py
[debug] check_if_theta 処理開始
[debug] [0]:[usb:003,013] [USB PTP Class Camera]
can't get debug descriptor: Resource temporarily unavailable
[debug] [' iProduct 2 RICOH THETA Z1\n']
[debug]シータです
[debug] check_if_thetaは正常終了
Exception in thread usb:003,013:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "/home/craig/Development/ricoh/multi_view_image/scripts/pytheta.py", line 236, in inner_start_capture
camera.set_config(camera_config) # En:Change to appropriate value. JP:値を適応
GPhoto2Error: [-1] Unspecified error
I don’t have the Z1 on hand, so I can’t test the operation at all.
I would like to improve the mutual understanding of the functions by enhancing the description of the comments out. This will increase the compatibility in other environments.
Yes, I finally departed from CLI-gPhoto2 in the latest update (2020/Oct/26). So there may be some testing in environments where this was not originally included.
@NaokiSato102, @jcasman and I have both forked the repository and can help you with the testing on different camera models as well as translation of the comments. We’re still trying to learn how to use GitHub fork and pull requests most effectively.
I was aware of this before you spoke to us. I’ve been asking for your advice on a regular basis, but I was surprised that you could help me directly. Thank you so much for your continued support.
- @jcasman and I are translating the documentation to help us practice using github fork and pull requests
- we’re using pydoc to convert the Python docstrings into html for pytheta.py. I’m still thinking of how to have both the Japanese and English in the same document.
- I’ve installed Ubuntu 16.04 on a separate SSD and have replicated your environment. I am still getting errors. I will test this more
- I am using pip and pipenv to create a Pipfile of the specific Python version and module used
- I installed the same version of gphoto2 as you did by compiling from source
$ gphoto2 --version
This version of gphoto2 is using the following software versions and options:
gphoto2 2.5.23 gcc, popt(m), exif, no cdk, aa, jpeg, readline
libgphoto2 2.5.23 all camlibs, gcc, ltdl, EXIF
libgphoto2_port 0.12.0 iolibs: disk ptpip serial usb1 usbdiskdirect usbscsi, gcc, ltdl, USB, serial without locking
current error
$ python main.py
[debug] check_if_theta 処理開始
[debug] [0]:[usb:003,009] [USB PTP Class Camera]
[debug] [' iProduct 2 RICOH THETA Z1\n']
[debug]シータです
[debug] check_if_thetaは正常終了
[/run/user/1000/gvfs/gphoto2:host=%5Busb%3A003%2C009%5D]はアンマウント済みです
[usb:003,009]
Exception in thread usb:003,009:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "/home/craig/Documents/Development/multi_view_image_modified/scripts/pytheta.py", line 274, in inner_start_capture
camera.set_config(camera_config) # EN: Change to appropriate value. JP:値を適応
GPhoto2Error: [-1] Unspecified error
[95]
['2822']
[95]
['2822']
Exception in thread usb:003,009:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "/home/craig/Documents/Development/multi_view_image_modified/scripts/pytheta.py", line 322, in inner_finish_capture
camera.set_config(camera_config) # JP: 値を適応 EN: Set value
GPhoto2Error: [-1] Unspecified error
I’m going to test the module functions individually next.
Really appreciate all the information and work on your side, Naoki-san! I have been looking at your documentation and hope to come back with some contributions soon.
It’s great to see that you’re making progress. Thanks for working on this, since being able to control a THETA (taking a video) is probably a key first step in robotics and other uses.
You should finish reformatting the documentation and make a pull request. I have the main functions working with a single camera. It’s a good example of using gphoto with Python.
Working on it right now!