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

15 views (last 30 days)
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

Answers (2)

Walter Roberson
Walter Roberson on 31 May 2017
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 on 31 May 2017
Edited: Matthew on 1 Jun 2017
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 Comments
Walter Roberson
Walter Roberson on 1 Jun 2017
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 on 1 Jun 2017
Edited: Matthew on 1 Jun 2017
Ah, then neither of the answers I wrote are relevant. Thanks for the explanation.

Sign in to comment.

Categories

Find more on MATLAB Support Package for Raspberry Pi Hardware in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!