Commit 52e31c7e authored by Andrey Filippov's avatar Andrey Filippov

added scripts for inter-channel synchronization

parent 4536aa6d
...@@ -2,6 +2,8 @@ DOCUMENTROOT=/www/pages ...@@ -2,6 +2,8 @@ DOCUMENTROOT=/www/pages
INCLUDES=$(DOCUMENTROOT)/include INCLUDES=$(DOCUMENTROOT)/include
OWN = -o root -g root OWN = -o root -g root
INSTDOCS = 0644 INSTDOCS = 0644
INSTEXE = 0755
#INSTALL = install #INSTALL = install
DOCS= favicon.ico \ DOCS= favicon.ico \
robots.txt robots.txt
...@@ -20,7 +22,13 @@ PHP_SCRIPTS=i2c.php \ ...@@ -20,7 +22,13 @@ PHP_SCRIPTS=i2c.php \
snapfull.php \ snapfull.php \
test_sensors.php \ test_sensors.php \
tuneseq.php \ tuneseq.php \
utils.php utils.php \
ts2frame.php \
reset_frames.php \
wait_frame.php
PHP_SCRIPTS_EXE=capture_range.php
PHPINCLUDES=i2c_include.php \ PHPINCLUDES=i2c_include.php \
show_source_include.php \ show_source_include.php \
...@@ -37,6 +45,7 @@ install: ...@@ -37,6 +45,7 @@ install:
$(INSTALL) $(OWN) -d $(DESTDIR)$(INCLUDES) $(INSTALL) $(OWN) -d $(DESTDIR)$(INCLUDES)
$(INSTALL) $(OWN) -m $(INSTDOCS) $(DOCS) $(DESTDIR)$(DOCUMENTROOT) $(INSTALL) $(OWN) -m $(INSTDOCS) $(DOCS) $(DESTDIR)$(DOCUMENTROOT)
$(INSTALL) $(OWN) -m $(INSTDOCS) $(PHP_SCRIPTS) $(DESTDIR)$(DOCUMENTROOT) $(INSTALL) $(OWN) -m $(INSTDOCS) $(PHP_SCRIPTS) $(DESTDIR)$(DOCUMENTROOT)
$(INSTALL) $(OWN) -m $(INSTEXE) $(PHP_SCRIPTS_EXE) $(DESTDIR)$(DOCUMENTROOT)
$(INSTALL) $(OWN) -m $(INSTDOCS) $(PHPINCLUDES) $(DESTDIR)$(INCLUDES) $(INSTALL) $(OWN) -m $(INSTDOCS) $(PHPINCLUDES) $(DESTDIR)$(INCLUDES)
$(INSTALL) $(OWN) -d $(DESTDIR)$(SYSCONFDIR) $(INSTALL) $(OWN) -d $(DESTDIR)$(SYSCONFDIR)
$(INSTALL) $(OWN) -d $(DESTDIR)$(CONFDIR) $(INSTALL) $(OWN) -d $(DESTDIR)$(CONFDIR)
......
...@@ -33,22 +33,34 @@ ...@@ -33,22 +33,34 @@
*! *!
*! *!
*/ */
if (count($_GET)==0) { include 'include/show_source_include.php';
if (count($_GET) < 1) {
echo <<<USAGE echo <<<USAGE
<p>This script returns camera variables as XML file, it also allows you to set those variables. Usually those changes will not take effect immediately - please use ccam.php that both changes variables and programs the camera to use them.</p> <p>This script returns camera variables as XML file, it also allows you to set those variables.
<p>The variable names to be read are specified without values (like camvar.php?WOI_WIDTH&WOI_HEIGHT ), the ones to be written - with the values (camvar.php?QUALITY=75). It is also possible to mix both types in the same request.</p> Usually those changes will not take effect immediately -
please use ccam.php that both changes variables and programs the camera to use them.</p>
<p>The variable names to be read are specified without values (like camvar.php?WOI_WIDTH&WOI_HEIGHT ),
the ones to be written - with the values (camvar.php?QUALITY=75). It is also possible to mix both types in the same request.</p>
<p>sensor_port=0..3 - specify which sensor port to use, default is sensor_port=0</p>
USAGE; USAGE;
exit (0); exit (0);
} }
$sensor_port=0;
$toRead=array(); $toRead=array();
$toWrite=array(); $toWrite=array();
foreach($_GET as $key=>$value) { foreach($_GET as $key=>$value) {
if ($key == 'sensor_port'){
$sensor_port = (integer) $value;
} else {
if ($value==="") $toRead[$key]=$value; if ($value==="") $toRead[$key]=$value;
else $toWrite[$key]=(integer) $value; else $toWrite[$key]=(integer) $value;
} }
$npars=(count($toWrite)>0)?elphel_set_P_arr($toWrite):0; }
if (count($toRead)>0) $toRead=elphel_get_P_arr($toRead); $npars=(count($toWrite)>0)?elphel_set_P_arr($sensor_port,$toWrite):0;
if ($_GET["STATE"]!==NULL) $toRead["STATE"]=elphel_get_state(); if (count($toRead)>0) $toRead=elphel_get_P_arr($sensor_port,$toRead);
if ($_GET["STATE"]!==NULL) $toRead["STATE"]=elphel_get_state(sensor_port);
$xml = new SimpleXMLElement("<?xml version='1.0' standalone='yes'?><camvars/>"); $xml = new SimpleXMLElement("<?xml version='1.0' standalone='yes'?><camvars/>");
foreach ($toRead as $key=>$value) { foreach ($toRead as $key=>$value) {
$xml->addChild ($key,$value); $xml->addChild ($key,$value);
......
#!/usr/bin/php
<?php
/*!*******************************************************************************
*! FILE NAME : capture_range.php
*! DESCRIPTION: Return frame number when the specified timestamp whil be reached
* or expected timestamp for the specified frame.
* Useful to synchronize multiple camera triggered by one of them
* when the master timestamp is sent to each camera. Normally
* used with just the master sensor port.
*
*! Copyright (C) 2021 Elphel, Inc
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*!
*/
include 'include/show_source_include.php';
$minahead = 2;
$PARS_FRAMES = 16;
$maxahead = $PARS_FRAMES - 3;
$flags = 0;
if (!($_SERVER ['REQUEST_METHOD'] == "GET")){
//Maybe re-write this in C or as a PHP function?
// CLI mode will be spawned bu the CGI and run in a background after request will be over
$sensor_port = $argv[1]; // $argv[0] - script name
$port_mask = $argv[2];
$frame = $argv[3]; // absolute frame to start compressor
$duration = $argv[4]; // number of frames to run compressor
if ($frame > 0){
$frame +=1; // seem there is a bug - actual compressed frames numbers (and last compressed frame number) are 1 less than expected
}
// If 'duration'==0 - just stop compressor, if 'duration' <0 - only start, if duration >0 - start+stop
// $f = fopen ( "/var/log/capture_range.log", 'a' );
// fwrite($f,"elphel_capture_range($sensor_port, $port_mask, $frame, $duration);\n");
// fclose ( $f );
elphel_capture_range($sensor_port, $port_mask, $frame, $duration);
// $f = fopen ( "/var/log/capture_range.log", 'a' );
// fwrite($f,"elphel_capture_range DONE\n");
// fclose ( $f );
exit(0);
}
// $output=null;
$retval=-1; // not used
// kill CLI mode if it was running (e.g. waiting for 100 years)
// exec("killall capture_range.php", $output, $retval);
// exec("/www/pages/capture_range.php 1 2 3 4 > /dev/null 2>&1 &");
if (count($_GET) < 1) {
print ("CGI mode");
echo <<<USAGE
<p>This script returns the timestamp for specified frame (frame=?) or expected frame number
when the specified timestamp (timestamp = ?.?) will be reached. If none of the frame number
and timestamp are specified - return last compressed frame number and timestamp.</p>
<p>Uses TRIG_PERIOD (in 10ns increments) for calculations.</p>
<p>sensor_port=0..3 - specify which sensor port to use, default is sensor_port=0</p>
USAGE;
exit (0);
}
$sensor_port=0;
$frame = 0;
$timestamp = 0.0;
$PARS_FRAMES = 16;
$maxahead = $PARS_FRAMES - 3;
$minahead = 2;
// $port_mask = 15; // not set - same as ts2frame.php
// $duration = 1; // not set - end, set - start
// $wait = false;
$extra = 2; // wait extra frames after stop to be sure compressor is flashed?
foreach($_GET as $key=>$value) {
if ($key == 'sensor_port'){
$sensor_port = (integer) $value;
} else if (($key == 'ts') || ($key == 'timestamp')){
$timestamp = (double) $value;
} else if (($key == 'f') || ($key == 'frame')){
$frame = (integer) $value;
} else if (($key == 'm') || ($key == 'port_mask')){
$port_mask = (integer) $value;
} else if (($key == 'd') || ($key == 'duration')){
$duration = (integer) $value;
} else if (($key == 'mxa') || ($key == 'maxahead')){
$maxahead = (integer) $value;
} else if (($key == 'mna') || ($key == 'minahead')){
$minahead = (integer) $value;
} else if (($key == 'w') || ($key == 'wait')){ // wait all done
$wait = true;
} else if (($key == 'e') || ($key == 'extra')){ // wait all done
$extra = (integer) $value;
}
}
if (($frame !=0) || ($timestamp !=0.0)) {
if (($frame <=0) && ($timestamp > 0.0)){
$frame = elphel_ts2frame($sensor_port,$timestamp);
}
$timestamp = elphel_frame2ts($sensor_port,$frame); // update, even if provided to fit better integer number of frames
}
$xml = new SimpleXMLElement("<?xml version='1.0' standalone='yes'?><capture_range/>");
$flags = 0;
if (isset($port_mask)){ // start or stop compressor
$this_frame = elphel_get_frame($sensor_port);
if ($frame == 0){ // e.g. to stop ASAP
if (isset ($duration)) {
elphel_compressor_run($sensor_port, 0, $flags, $port_mask); // turn on ASAP
$xml->addChild ('compressor', 1);
} else {
elphel_compressor_stop($sensor_port, 0, $flags, $port_mask);// turn off ASAP
$xml->addChild ('compressor', 0);
}
$frame = $this_frame + $minahead;
}
$ahead = $frame - $this_frame;
if ($ahead < $minahead) {
$xml->addChild ('error','TOO LATE');
$xml->addChild ('ahead',$ahead);
} else { // OK, enough time to program
if (!isset($duration)) {
$duration = 0;
}
// kill CLI mode if it was running (e.g. waiting for 100 years)
exec("killall capture_range.php", $output, $retval);
// spawn CLI program in background duration <0 - start only, ==0 - stop only, >0 - start+stop
// $f = fopen ( "/var/log/capture_range.log", 'a' );
// fwrite($f,"exec(/www/pages/capture_range.php $sensor_port $port_mask $frame $duration > /dev/null 2>&1 &\n");
// fclose ( $f );
exec("/www/pages/capture_range.php $sensor_port $port_mask $frame $duration > /dev/null 2>&1 &");
// $f = fopen ( "/var/log/capture_range.log", 'a' );
// fwrite($f,"DONE exec\n");
// fclose ( $f );
if ($duration > 0){
$frame += $duration; // xml will contain end frame
}
if ($wait){
elphel_wait_frame_abs($sensor_port, $frame + 1);
}
}
} else { // just ts2frame.php mode
if ($frame == 0){
$timestamp = elphel_frame2ts($sensor_port,0);
$frame = elphel_ts2frame($sensor_port,0.0);
}
}
$xml->addChild ('retval', $retval);
$xml->addChild ('frame',$frame);
$xml->addChild ('timestamp',$timestamp);
$this_frame=elphel_get_frame($sensor_port);
$xml->addChild ('this_frame',$this_frame);
$xml->addChild ('this_timestamp',elphel_frame2ts($sensor_port,$this_frame));
// $xml->addChild ('frame',$frame);
// $xml->addChild ('timestamp',$timestamp);
$rslt=$xml->asXML();
header("Content-Type: text/xml");
header("Content-Length: ".strlen($rslt)."\n");
header("Pragma: no-cache\n");
printf($rslt);
?>
<?php
/*!*******************************************************************************
*! FILE NAME : reset_frames.php
*! DESCRIPTION: reset all sensor channels frame numbers (including hardware sequencer)
* May be needed at least once before (and after?) switching from
* free-running mode to all channels triggered from the common source.
* Optional parameter frame: if frame >0 - wait for the specified absolute
* frame number on a master port, frame <= 0 - skip frames before resetting
* Default is frame = -1, it waits fro the new frame (on master port) before
* resetting all channels.
* Resetting disturbs frame sequencer, so it is better not to apply any
* frame commands 16 frames before this command as they may be lost.
*
*! Copyright (C) 2021 Elphel, Inc
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*!
*/
include 'include/show_source_include.php';
$sysfs_all_frames = '/sys/devices/soc0/elphel393-framepars@0/all_frames'; // read all frames, write - reset frames
$frame = -1; // positive - wait absolute frame number for the master port, negative - skip frame(s)
foreach($_GET as $key=>$value) {
if (($key == 'f') || ($key == 'frame')){
$frame = (integer) $value;
}
}
$f = @fopen($sysfs_all_frames, "w");
if ($f===false) {
$xml = new SimpleXMLElement("<?xml version='1.0' standalone='yes'?><error/>");
$xml->addChild ('error',print_r(error_get_last(),1));
} else {
$fw=@fwrite($f, strval($frame));
if ($fw===false){
$xml = new SimpleXMLElement("<?xml version='1.0' standalone='yes'?><error/>");
$xml->addChild ('error',print_r(error_get_last(),1));
} else {
fclose($f);
$xml = new SimpleXMLElement("<?xml version='1.0' standalone='yes'?><reset_frames/>");
$xml->addChild ('frame',$frame);
}
}
$rslt=$xml->asXML();
header("Content-Type: text/xml");
header("Content-Length: ".strlen($rslt)."\n");
header("Pragma: no-cache\n");
printf($rslt);
?>
\ No newline at end of file
<?php
/*!*******************************************************************************
*! FILE NAME : ts2frame.php
*! DESCRIPTION: Return frame number when the specified timestamp whil be reached
* or expected timestamp for the specified frame.
* Useful to synchronize multiple camera triggered by one of them
* when the master timestamp is sent to each camera. Normally
* used with just the master sensor port.
*
*! Copyright (C) 2021 Elphel, Inc
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*!
*/
include 'include/show_source_include.php';
if (count($_GET) < 1) {
echo <<<USAGE
<p>This script returns the timestamp for specified frame (frame=?) or expected frame number
when the specified timestamp (timestamp = ?.?) will be reached. If none of the frame number
and timestamp are specified - return last compressed frame number and timestamp.</p>
<p>Uses TRIG_PERIOD (in 10ns increments) for calculations.</p>
<p>sensor_port=0..3 - specify which sensor port to use, default is sensor_port=0</p>
USAGE;
exit (0);
}
$sensor_port=0;
$frame = 0;
$timestamp=0.0;
$toWrite=array();
foreach($_GET as $key=>$value) {
if ($key == 'sensor_port'){
$sensor_port = (integer) $value;
} else if (($key == 'ts') || ($key == 'timestamp')){
$timestamp = (double) $value;
} else if (($key == 'f') || ($key == 'frame')){
$frame = (integer) $value;
}
}
if ($frame > 0){
$timestamp = elphel_frame2ts($sensor_port,$frame);
} else if ($timestamp > 0.0){
$frame = elphel_ts2frame($sensor_port,$timestamp);
} else {
$timestamp = elphel_frame2ts($sensor_port,0);
$frame = elphel_ts2frame($sensor_port,0.0);
}
$xml = new SimpleXMLElement("<?xml version='1.0' standalone='yes'?><ts2frame/>");
$xml->addChild ('frame',$frame);
$xml->addChild ('timestamp',$timestamp);
$rslt=$xml->asXML();
header("Content-Type: text/xml");
header("Content-Length: ".strlen($rslt)."\n");
header("Pragma: no-cache\n");
printf($rslt);
?>
<?php
/*!*******************************************************************************
*! FILE NAME : wait_frame.php
*! DESCRIPTION: Wait for absolute frame number (frame>0) or skip frames (frames <0),
*! on the specified port (default sensor_port=0)
*! Default frame=-1 (skip 1 frame).
*! Copyright (C) 2021 Elphel, Inc
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*!
*/
include 'include/show_source_include.php';
$frame = -1; // positive - wait absolute frame number for the master port, negative - skip frame(s)
$sensor_port = 0;
foreach($_GET as $key=>$value) {
if ($key == 'sensor_port'){
$sensor_port = (integer) $value;
} else if (($key == 'f') || ($key == 'frame')){
$frame = (integer) $value;
}
}
if ($frame < 0) {
elphel_skip_frames($sensor_port, -$frame);
} else if ($frame > 0) {
elphel_wait_frame_abs ($sensor_port, $frame);
}
$this_frame = elphel_get_frame($sensor_port);
$xml = new SimpleXMLElement("<?xml version='1.0' standalone='yes'?><wait_frames/>");
$xml-> addChild ('frame',$this_frame);
$rslt=$xml->asXML();
header("Content-Type: text/xml");
header("Content-Length: ".strlen($rslt)."\n");
header("Pragma: no-cache\n");
printf($rslt);
?>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment