How do I get "system" command to not wait for raspberry pi to reply

10 ビュー (過去 30 日間)
danhf
danhf 2017 年 5 月 30 日
編集済み: Matthew 2017 年 6 月 1 日
I'm trying to pull raw images from the cameraboard through matlab.
Currently, I'm running this command:
system(rpi,'raspistill -t 1 -ISO 100 --raw -ss 100000 -ev 5 -o rawtemp.jpg');
This works fine, except it takes 2 seconds (plus exposure time) to execute because the camera has to be turned on from scratch for every call. I also have to pull the data off the pi to my computer and process it into a useable array, which takes another 2 seconds.
What I'd like to do is to be able to run that system command, and then have matlab run other stuff in the meantime while the pi is collecting the photo. That way, I can do the two seconds of processing work from a previous image while taking the next one. From what I read, adding an "&" to the end of the command should work:
system(rpi,'raspistill -t 1 -ISO 100 --raw -ss 100000 -ev 5 -o rawtemp.jpg &');
but it doesn't seem to have any effect.
I tried running the command directly on the pi and the & command does work there, so it's something on the matlab side.
I've also considered trying to put the camera into signal mode with a -s and switching the time to -t 0, but then matlab just sits and waits and can't ever send a trigger command because it's just waiting for the pi to finish (which it never will because of the -t 0 command).
Any help would be very welcome here :P
Thanks!
Dan
EDIT:
I started looking more into the parallel computing functions and found that the "batch" function seems to work well:
j = batch('system',0,{rpi,'raspistill -t 0 -ISO 100 --raw -ss 100000 -ev 5 -o rawtemp.jpg'});
This still takes 0.6 seconds to run, but it's better than the 3 or so seconds it takes to actually take the shot. Then when I'm ready to use the photo, I can just run
wait(j)
to make sure the raspi has finished doing its thing, and then pull the file from the pi into matlab.
Next I tried to see if I could apply this to signal mode with moderate success.
First, run the infinite background process (by changing t to 0 and adding the -s to enter signal mode):
j = batch('system',0,{rpi,'raspistill -t 0 -s -ISO 100 --raw -ss 100000 -ev 5 -o rawtemp.jpg'});
Then I can call
system(rpi,'pkill -USR1 raspistill');
This line takes less time than the pi takes to save the photo to storage, so it needs a pause afterwards (.75 seconds seems to reliably do the trick).
The problem I have now is I have no idea what to do if I need to change the camera settings. The camera is being occupied indefinitely and won't take any raspistill commands other than the signal (pkill) command. Any idea how to shut down the original raspistill signal setup to be able to send over a new one?
Thanks again!
Dan

回答 (2 件)

Walter Roberson
Walter Roberson 2017 年 5 月 31 日
Adding & is a correct method for allowing the system() call to return before the processing has finished. However you need to be careful because you are using the same output file name each time. You would be safer requesting a different output file for each iteration.
You would also be safer if you used some kind of signaling mechanism to indicate that the processing is finished. For example,
system(rpi, sprintf('(raspistill -t 1 -ISO 100 --raw -ss 100000 -ev 5 -o %04d_rawtemp.jpg; echo ready > %04d_ready) &', Iteration_number, Iteration_number) );
The flag file such as 0026_ready would not be created until the raspistill command creating 0026_rawtemp.jpg was complete. This takes the guess-work out of whether command finished: you can check with
system(rpi, sprintf( 'test -f %04d_ready', Iteration_number) )
that would return 0 if the file exists, and non-zero (probably 1) if the file does not exist

Matthew
Matthew 2017 年 5 月 31 日
編集済み: Matthew 2017 年 6 月 1 日
Dan,
One thing to look into is the process object, as it allows you to start independent processes. I've sketched what the code might look like below, but the code would need updating to correct the FileName and Arguments parameters.
proc = System.Diagnostics.Process;
proc.StartInfo.FileName = fullfile(rpiPath,rpiExeName);
proc.StartInfo.Arguments = 'raspistill -t 0 -ISO 100 --raw -ss 100000 -ev 5 -o rawtemp.jpg';
proc.Start(); % Start the process
If you are running Matlab in a windows environment, the other command to look at is the background command that you can use within the system call. Credit for this goes to the linked stack overflow conversation.
[status,out] = system('start /b /min myprogram.exe');
Edit to clarify that start /b will only work if Matlab is running on a windows environment, and the base program 'rpi' is a windows executable
  4 件のコメント
Walter Roberson
Walter Roberson 2017 年 6 月 1 日
It does an ssh to run the command; this does not involve explicitly using a local shell (it can fork the process directly, or use java)
Matthew
Matthew 2017 年 6 月 1 日
編集済み: Matthew 2017 年 6 月 1 日
Ah, then neither of the answers I wrote are relevant. Thanks for the explanation.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeMATLAB Support Package for Raspberry Pi Hardware についてさらに検索

製品

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by