Python Script Calling CHDKPTP CLI Commands on Raspberry Pi - page 2 - General Discussion and Assistance - CHDK Forum  

Python Script Calling CHDKPTP CLI Commands on Raspberry Pi

  • 19 Replies
  • 16833 Views
*

Offline reyalp

  • ******
  • 14080
Re: Python Script Calling CHDKPTP CLI Commands on Raspberry Pi
« Reply #10 on: 09 / August / 2015, 17:52:49 »
Advertisements
So I've written a Python script with the help of a friend. I've attached it.

The script is still a little "wobbly" and we're ironing out the bugs. But one of them seems to be related to CHDKPTP?

Here's the command line:

Code: [Select]
[2015-08-09 20:45:19] Check if camera is On. camera_error state: False
-e'exec if not con:is_connected() then os.exit(1) end'
open_camera_dev_usb: ptp_opensession failed 0x2ff
open_camera_dev_usb:usb_ptp_device_reset(): Device or resource busy
usb_ptp_get_device_status(): Device or resource busy
open_camera_dev_usb: ptp_opensession 2 failed: 0x2ff
ERROR: connection failed

So what happens is that I check if the camera is on by sending the code that reyalp suggested. The camera is on but the communication to the USB seems to go wrong?
I'm not really clear what you are doing here. The -e command you quoted does not attempt to open a connection, so cannot generate the error you quoted by itself.

If you post the entire command or sequence of commands, that would give me a better chance to figure out what is going on.

Most of the times I've seen
Quote
Device or resource busy
The camera was actually open by some other process, either another CHDK client or something from the OS (the latter is more likely on Linux, since libusb prevents regular OS stuff from talking to the camera on windows)
However, the reset will generally kick the other application off, which doesn't appear to have happened in this case.
Don't forget what the H stands for.

*

Offline JvdP

  • ***
  • 174
Re: Python Script Calling CHDKPTP CLI Commands on Raspberry Pi
« Reply #11 on: 10 / August / 2015, 05:10:00 »
I'm not really clear what you are doing here. The -e command you quoted does not attempt to open a connection, so cannot generate the error you quoted by itself.

If you post the entire command or sequence of commands, that would give me a better chance to figure out what is going on.
Yes, I'm sorry. I was aware that it was confusing, however I don't want to post the whole script without the consent of my friend who helped me write it. This shouldn't be a problem and I would love to share the script for others to use it, so I will probably be posting it soon.

Here are the functions in the script that are involved with checking/turning on the camera.

Code: [Select]
''' send command c to camera using chdk '''
def chdk_send_cmd(c="-e 'exec if not con:is_connected() then os.exit(1) end'"):
    print c
    return subprocess.call("chdkptp -c {}".format(c), shell=True)

Code: [Select]
''' This command checks if the camera is on. Returns True if on '''
def camera_is_on():
    if chdk_send_cmd() == 0:
        return True
    elif chdk_send_cmd() == 1:
        return False
    else:
        raise Exception("Unable to determine state of camera")

Code: [Select]
''' Will reboot the camera after a delay, default delay is 10 sec '''
def reboot_camera(delay = 10):
    Timer(delay, trigger_relay, ()).start() #Send stop command to camera
    time.sleep(delay + 4) #wait for camera to start back up
    if camera_is_on(): # Check if camera has started using camera_is_on() function
        chdk_send_cmd("-e'rec' -e'luar set_mf(1)' -e'luar set_focus(40000)'") #Put camera in record mode,set focus to manual, then focus to a specific distance
        camera_error.clear()
        capture_loop() # restart capture_loop
    else: # If camera fails to start, raise an exception
        raise Exception("Unable to reboot camera")

The problem occurs in the function to reboot the camera. I have no problems with running this function manually. I'm thinking it has something to do with the other functions in the script.

The same script also takes care of sending a remoteshoot (rs) over shell to CHDKPTP. I think that it is possible that the script tries to communicate the rs to the camera at the same time (or at least very quickly sequentially) it tries to check if the camera is on. I suppose that this would cause the "device or resource busy" error...

Quote
Most of the times I've seen
Quote
Device or resource busy

The camera was actually open by some other process, either another CHDK client or something from the OS (the latter is more likely on Linux, since libusb prevents regular OS stuff from talking to the camera on windows)
However, the reset will generally kick the other application off, which doesn't appear to have happened in this case.

I've already made sure that the Raspbian Wheezy OS doesn't automatically mount the camera as it is connected. I'm not sure what else the OS is doing with the camera but it shouldn't cause any problems.
« Last Edit: 10 / August / 2015, 05:23:16 by JvdP »

*

Offline reyalp

  • ******
  • 14080
Re: Python Script Calling CHDKPTP CLI Commands on Raspberry Pi
« Reply #12 on: 10 / August / 2015, 16:35:10 »
The same script also takes care of sending a remoteshoot (rs) over shell to CHDKPTP. I think that it is possible that the script tries to communicate the rs to the camera at the same time (or at least very quickly sequentially) it tries to check if the camera is on. I suppose that this would cause the "device or resource busy" error...
You absolutely must have only one connection at a time to the camera. This is a limitation of the camera firmware. If you are using multiple threads in your python program, you will need to synchronize any that attempt to communicate with the camera.

Opening/closing connections close together may also cause problems. In general, I'd favor just keeping one chdkptp process open and feeding the commands to it's stdin, but this may not be practical for every application.

Quote
I've already made sure that the Raspbian Wheezy OS doesn't automatically mount the camera as it is connected. I'm not sure what else the OS is doing with the camera but it shouldn't cause any problems.
If it's not auto-mounting it should probably be OK.
Don't forget what the H stands for.

*

Offline JvdP

  • ***
  • 174
Re: Python Script Calling CHDKPTP CLI Commands on Raspberry Pi
« Reply #13 on: 10 / August / 2015, 17:12:51 »
I've attached the latest version of the script to the start post. Feel free to take a look.

We're currently working on implementing a "communication flag" which will flag whether a script wants to communicate with the camera and prevents any process from communicating while another communication is ongoing.

I really don't have enough knowledge of how to open a single session to CHDKPTP and feed it with STDIN. I'm afraid we might go with this quick and dirty solution if there isn't any super important reason why we shouldn't. However, this doesn't mean I don't dislike your input reyalp, it is actually very welcome.

« Last Edit: 10 / August / 2015, 17:27:52 by JvdP »


*

Offline reyalp

  • ******
  • 14080
Re: Python Script Calling CHDKPTP CLI Commands on Raspberry Pi
« Reply #14 on: 10 / August / 2015, 23:59:29 »
I've attached the latest version of the script to the start post. Feel free to take a look.
My python knowledge is minimal (should fix that one of these days  :-[), so I'm not likely to be much help with the python parts.

You might find it simpler to just put your camera check in the same loop as shooting, since it has to happen sequentially anyway.

edit:
I would definitely expect problems if the current code is just running the status check and shooting loops in parallel without any synchronization.

Quote
I'm afraid we might go with this quick and dirty solution if there isn't any super important reason why we shouldn't.
Quick in dirty is fine as long as it's good enough. The main thing to watch out for is that there is some (uncertain) delay between when you disconnect and when you can connect again.
« Last Edit: 11 / August / 2015, 00:19:23 by reyalp »
Don't forget what the H stands for.

*

Offline adong

  • **
  • 66
Re: Python Script Calling CHDKPTP CLI Commands on Raspberry Pi
« Reply #15 on: 11 / August / 2015, 08:24:44 »
I took a quick look at your script:

apart from the pep8 remarks I could make,

camera_is_on calls two times chdk_send_cmd if camera is off, but I'm not even sure it can reach there. Anyway, store the result of chdk_send_cmd, then compare.

Exceptions should be raised in chdk_send_cmd, else you'll have to handle that everywhere and it's a pain.

Trigger relay does way more than trigger, it also initializes the board gpio. Calling it too much may cause issues. Just split it into a setup() and the actual triggering.

reboot camera is /very/ fragile and highly depends on the fact the the camera boots in X seconds. You could make it so that it periodically checks if you can connect to the camera, then set it up.

Finally, the biggest issue is that you have multiple processes that run chdkptp at the same time, and it will probably crash the camera. I don't think you need to use multiprocessing at all, it just makes the code flow very complicated.

Keep it simple:

check if camera is connected
if it's not, boot it
setup camera
as long as we don't want to stop, just take pictures
catch errors from chdkptp and handle correctly
 
I would recommend trying to use jbaiter's bindings. Some issues just got ironed out a few weeks ago.


*

Offline JvdP

  • ***
  • 174
Re: Python Script Calling CHDKPTP CLI Commands on Raspberry Pi
« Reply #16 on: 11 / August / 2015, 18:10:04 »
Thanks for the feedback adong, I will be implementing changes you have suggested.

Does anybody know if I could get the get_mode() result into my python script? Kind of in the way I use chdkptp to detect if the camera is connected. Or is this a limitation with regards to return commands of CHDKPTP?

*

Offline reyalp

  • ******
  • 14080
Re: Python Script Calling CHDKPTP CLI Commands on Raspberry Pi
« Reply #17 on: 11 / August / 2015, 21:55:43 »
Does anybody know if I could get the get_mode() result into my python script? Kind of in the way I use chdkptp to detect if the camera is connected. Or is this a limitation with regards to return commands of CHDKPTP?
When you use luar, the results are printed. So you would have to parse the output to use get_mode() this way. However, if you use chdkptp Lua calls, you can get the result back in chdkptp lua, and then use it exactly the same ways as "is_connected"

Something like
Code: [Select]
-e'exec if not con:execwait([[return get_mode()]]) then ...
Note that execwait will throw an error if there is a ptp error like the camera not being connected. Assuming you ran the code with exec, that exec call will end and the error will be printed. You can use execwait_pcall if you want to check for errors like that in your code.

If you used chdkptp.py, you could presumably have values like this returned directly to your python code.

edit to clarify:
In the above example, con:execwait returns the values that the camera get_mode() returns in chdkptp side lua.
Don't forget what the H stands for.


*

Offline JvdP

  • ***
  • 174
Re: Python Script Calling CHDKPTP CLI Commands on Raspberry Pi
« Reply #18 on: 16 / August / 2015, 08:42:31 »
I'm in the middle of adjusting the script so I can take use of chdkptp.py. Does this actually allow for a remoteshoot command? Or can I only shoot and then download the image manually?

*

Offline reyalp

  • ******
  • 14080
Re: Python Script Calling CHDKPTP CLI Commands on Raspberry Pi
« Reply #19 on: 16 / August / 2015, 14:14:00 »
I'm in the middle of adjusting the script so I can take use of chdkptp.py. Does this actually allow for a remoteshoot command? Or can I only shoot and then download the image manually?
From
https://github.com/jbaiter/chdkptp.py/blob/master/chdkptp/device.py

it looks like shoot with the "stream" option is remoteshoot

You should also be able to call any chdk lua function, so in theory you ought to be able to use cli:execute, but it looks like the cli module isn't loaded, instead there are a few stubs to replace it, see _setup_runtime https://github.com/jbaiter/chdkptp.py/blob/master/chdkptp/lua.py

(take all this with  a grain of salt, as my python knowledge is very limited and I've only skimmed the source)
Don't forget what the H stands for.

 

Related Topics