Commit 88f9f20e authored by Andrey Filippov's avatar Andrey Filippov

added configuration file

parent 70cb390d
motosat_ip= "192.168.1.250"
modem_ip = "192.168.0.1"
AZ_CPD = 12.74445
EL_CPD = 75.78567
SK_CPD = 8.34;
AZ_0 = 0.0; // degrees
EL_0 = 0.0; // degrees
SK_0 = 55.7554; // degrees
AZ_CMAX = 4790;
EL_CMAX = 10979;
SK_CMAX = 931;
MODEM_THRESHOLD = 17.0; // consider something if modem strength is above
OVERSHOOT = 2; // 1; // final steps absolute error
LATE_STOP_AZ = 30; // steps
;; Rescan azimuth after noticed a satellite during area scan
AZ_PLAY = 1.0; // Hysteresis caused by mechanical play (degrees)
AZ_RESCAN = 8; // (degrees) around expected center
AZ_RESCAN_STEP = 0.5; // (degrees)
EL_PLAY = 1.0; // Hysteresis caused by mechanical play (degrees)
EL_RESCAN = 8; // (degrees) around expected center
EL_RESCAN_STEP = 0.5; // (degrees)
AZ_2D_RANGE = 2.0; // degrees 2D peaking scan azimuth (full range)
EL_2D_RANGE = 3.0; // degrees 2D peaking scan alevation (full range)
AZ_2D_STEP = 0.25; // degrees
EL_2D_STEP = 0.4; // degrees
ADJUST_2D = 1; // 1 - adjust 2D, 0 - skip (only separate azimuth and elevation
USABLE_FRACT = 0.6; // use ony samples not less than this fraction of maximal
USABLE_POW = 1.0; // transform (maxstrengh - strengh) by applying pow - 1.2 ...1.3 may have marginal improvements
ARGMAX_OURSIDE = 0.2; // Allow argmax outside of the measured range by this fraction
ARGMAX_OURSIDE_2D = 0.0; // Allow argmax outside of the measured range by this fraction during 2D peaking
;; Modem never allows wrong satellite to have signal strength above 29, and tries to maintain 30 for the correct one when the signal falls below.
;; So these values can not be used for peaking(maybe only remove 30 if the signal is going down?)
;;HUGHES_BAD_STRENGTHS = array(29,30);
HUGHES_BAD_STRENGTHS[0] = 29;
HUGHES_BAD_STRENGTHS[1] = 30;
HUGHES_THRESHOLD = 30; // if less - wrong satellite
GUARD_AZIMUTH = 2.0; // (degrees) do not look for satellites closer than this to alerady found
GUARD_STEP = 1.0; // (degrees) If will peak on the same satellite, increase guard range on that side
AZ_TOL = 0.7; // (degrees) If satellites azimuths differ by less than this - they are the same
MAX_ARC_TILT = 0.2; // maximal local satellite arc tilt near a known satellite
SAT_AZ_STEP = 0.5; // (degrees) mark found satellites with this resolution
LOG_PATH = "/home/eyesis/git/motosat/attic/logs/test07.log";
<?php
require_once('PolynomialApproximation.php');
//$CONFIG_PATH= "/home/eyesis/git/motosat/motosat.conf";
$CONFIG_PATH= dirname(get_included_files()[0])."/motosat.conf1";
// Values to use if no config file is provided:
$motosat_ip= "192.168.1.250";
$modem_ip = "192.168.0.1";
$AZ_CPD = 12.74445;
$EL_CPD = 75.78567;
$SK_CPD = 8.34;
$AZ_0 = 0.0; // degrees
$EL_0 = 0.0; // degrees
$SK_0 = 55.7554; // degrees
$AZ_CMAX = 4790;
$EL_CMAX = 10979;
$SK_CMAX = 931;
$MODEM_THRESHOLD = 17.0; // consider something if modem strength is above
$OVERSHOOT = 2; // 1; // final steps absolute error
$LATE_STOP_AZ = 30; // steps
// Rescan azimuth after noticed a satellite during area scan
$AZ_PLAY = 1.0; // Hysteresis caused by mechanical play (degrees)
$AZ_RESCAN = 8; // (degrees) around expected center
$AZ_RESCAN_STEP = 0.5; // (degrees)
$EL_PLAY = 1.0; // Hysteresis caused by mechanical play (degrees)
$EL_RESCAN = 8; // (degrees) around expected center
$EL_RESCAN_STEP = 0.5; // (degrees)
$AZ_2D_RANGE = 2.0; // degrees 2D peaking scan azimuth (full range)
$EL_2D_RANGE = 3.0; // degrees 2D peaking scan alevation (full range)
$AZ_2D_STEP = 0.25; // degrees
$EL_2D_STEP = 0.4; // degrees
$ADJUST_2D = 1; // 1 - adjust 2D, 0 - skip (only separate azimuth and elevation
$USABLE_FRACT = 0.6; // use ony samples not less than this fraction of maximal
$USABLE_POW = 1.0; // transform (maxstrengh - strengh) by applying pow - 1.2 ...1.3 may have marginal improvements
$ARGMAX_OURSIDE = 0.2; // Allow argmax outside of the measured range by this fraction
$ARGMAX_OURSIDE_2D = 0.0; // Allow argmax outside of the measured range by this fraction during 2D peaking
// Modem never allows wrong satellite to have signal strength above 29, and tries to maintain 30 for the correct one when the signal falls below.
// So these values can not be used for peaking(maybe only remove 30 if the signal is going down?)
$HUGHES_BAD_STRENGTHS = array(29,30);
$HUGHES_THRESHOLD = 30; // if less - wrong satellite
$GUARD_AZIMUTH = 2.0; // (degrees) do not look for satellites closer than this to alerady found
$GUARD_STEP = 1.0; // (degrees) If will peak on the same satellite, increase guard range on that side
$AZ_TOL = 0.7; // (degrees) If satellites azimuths differ by less than this - they are the same
$MAX_ARC_TILT = 0.2; // maximal local satellite arc tilt near a known satellite
$SAT_AZ_STEP = 0.5; // (degrees) mark found satellites with this resolution
$LOG_PATH = "/home/eyesis/git/motosat/attic/logs/test07.log";
//
$ini_double = array(
'AZ_CPD',
'EL_CPD',
'SK_CPD',
'AZ_0',
'EL_0',
'SK_0',
'MODEM_THRESHOLD',
'AZ_PLAY',
'AZ_RESCAN',
'AZ_RESCAN_STEP',
'EL_PLAY',
'EL_RESCAN',
'EL_RESCAN_STEP',
'AZ_2D_RANGE',
'EL_2D_RANGE',
'AZ_2D_STEP',
'EL_2D_STEP',
'USABLE_FRACT',
'USABLE_POW',
'ARGMAX_OURSIDE',
'ARGMAX_OURSIDE_2D',
'HUGHES_THRESHOLD',
'GUARD_AZIMUTH',
'GUARD_STEP',
'AZ_TOL',
'MAX_ARC_TILT',
'SAT_AZ_STEP'
);
$ini_int = array(
'AZ_CMAX',
'EL_CMAX',
'SK_CMAX',
'OVERSHOOT',
'LATE_STOP_AZ',
'ADJUST_2D',
'HUGHES_BAD_STRENGTHS'
);
//print_r(parse_ini_file("/home/eyesis/git/motosat/motosat.conf"));
foreach (parse_ini_file($CONFIG_PATH) as $key => $value) {
if (in_array($key, $ini_int)) {
if (is_array($value)) {
$ivalue = array();
foreach ($value as $k => $v){
$ivalue[$k]= intval($v);
}
$GLOBALS[$key] =$ivalue;
} else {
$GLOBALS[$key] = intval($value);
}
} else if (in_array($key, $ini_double)) {
if (is_array($value)) {
$dvalue = array();
foreach ($value as $k => $v){
$dvalue[$k]= doubleval($v);
}
$GLOBALS[$key] =$dvalue;
} else {
$GLOBALS[$key] = doubleval($value);
}
} else {
$GLOBALS[$key] = $value;
}
}
echo show_vars(array(
'motosat_ip',
'modem_ip',
'AZ_CPD',
'EL_CPD',
'SK_CPD',
'AZ_0',
'EL_0',
'SK_0',
'AZ_CMAX',
'EL_CMAX',
'SK_CMAX',
'MODEM_THRESHOLD',
'OVERSHOOT',
'LATE_STOP_AZ',
'AZ_PLAY',
'AZ_RESCAN',
'AZ_RESCAN_STEP',
'EL_PLAY',
'EL_RESCAN',
'EL_RESCAN_STEP',
'AZ_2D_RANGE',
'EL_2D_RANGE',
'AZ_2D_STEP',
'EL_2D_STEP',
'ADJUST_2D',
'USABLE_FRACT',
'USABLE_POW',
'ARGMAX_OURSIDE',
'ARGMAX_OURSIDE_2D',
'HUGHES_BAD_STRENGTHS',
'HUGHES_THRESHOLD',
'GUARD_AZIMUTH',
'GUARD_STEP',
'AZ_TOL',
'MAX_ARC_TILT',
'SAT_AZ_STEP',
'LOG_PATH'
));
exit(0);
$motosat_url= "http://".$motosat_ip."/motor.xml";
$modem_strengt_url = "http://".$modem_ip."/sqf/sqfdisp/index.html";
/*
http://192.168.1.250/motor.xml?Action=ElUp&Distance=0.5&Units=1 0.5 degree up
http://192.168.1.250/motor.xml?Action=ElUp&Distance=1&Units=0 1 step up
http://192.168.1.250/motor.xml?Action=ElDn&Distance=1&Units=0 1 step down
http://192.168.1.250/motor.xml?Action=AzUp&Distance=1&Units=0 1 sep az +
http://192.168.1.250/motor.xml?Action=AzDn&Distance=1&Units=0 1 sep az -
SK0 = 465 steps
http://192.168.1.250/motor.xml?Action=SkUp&Distance=1&Units=0 1 step sk +
http://192.168.1.250/motor.xml?Action=SkDn&Distance=1&Units=0 1 step sk -
http://192.168.1.250/motor.xml?Action=Stop&Distance=100&Units=1 - stop
*/
//php > var_dump($DishAngle);
//array(3) {[0]=> float(9.97), [1]=> float(0), [2]=> float(0)}
$dbg_file = fopen($LOG_PATH,"w");
//fprintf($dbg_file,"test log\n");
if (false) {
$arr = Array(5,6,7,9,9,10,11,11,12,12,11,11,10,10,10,36,40,45,47,51,51,51,49,48,43,38,30,30,30,10,10,10,10);
$rslt = findMax1d($arr, $USABLE_FRACT, $USABLE_POW, $ARGMAX_OURSIDE);
print_r($rslt);
print("\n");
// Try 2D:
$arr2d = array();
$rows = sizeof($arr);
$cols = $rows;
for ($i= 0; $i < $rows; $i++){
$line = $arr;
for ($j= 0; $j < $cols; $j++){
$i1 = ($i + 10) % $rows;
$line[$j] *= $arr[$i1]/51;
$line[$j] += rand(-10,10);
if ($line[$j] <1){
$line[$j] = 1;
}
}
$arr2d [] = $line;
}
// $rslt = findMax2d($arr2d, $USABLE_FRACT, $USABLE_POW, $ARGMAX_OURSIDE);
$rslt = findMax2d($arr2d, 0.55, $USABLE_POW, $ARGMAX_OURSIDE);
var_dump($rslt);
exit (0);
}
if (false) {
print("<p>".date('l jS \of F Y h:i:s A')."</p>");
$modem_strength= getModemStrength();
for ($i=0;$i<10;$i++){
//$modem_strength= getModemStrength();
$xml_state = simplexml_load_file($motosat_url); // 0.29 sec
}
print("<p>modem_strength=".$modem_strength." file=".$modem_strengt_url."</p>");
print("<p>".date('l jS \of F Y h:i:s A')."</p>");
exit (0);
}
$xml_state = simplexml_load_file($motosat_url); // use current as default gor HTTP GET
//$DishCount = getDishCounts (xml_state);
$DishAngle = getDishAngles ($xml_state);
$dbg = false; // true;
$multi= true; // false;
$wnd_az = 0;
$wnd_el = 0;
$scan_step = 1.0;
$min_strength = $MODEM_THRESHOLD;
$full_search = 0;
if (isset($_GET["dbg"])) { $dbg=myval($_GET["dbg"]);}
if (isset($_GET["multi"])) { $multi=myval($_GET["multi"]);}
if (isset($_GET["az"])) { $DishAngle[0] = myfval($_GET["az"]);}
if (isset($_GET["el"])) { $DishAngle[1] = myfval($_GET["el"]);}
if (isset($_GET["sk"])) { $DishAngle[2] = myfval($_GET["sk"]);}
if (isset($_GET["wnd_az"])) { $wnd_az = myfval($_GET["wnd_az"]);}
if (isset($_GET["wnd_el"])) { $wnd_el = myfval($_GET["wnd_el"]);}
if (isset($_GET["scan_step"])) { $scan_step = myfval($_GET["scan_step"]);}
if (isset($_GET["min_strength"])) { $min_strength = myfval($_GET["min_strength"]);}
if (isset($_GET["full_search"])) { $full_search = 1;}
$scan_mode = ($wnd_az > 0) || ($wnd_el > 0);
if (!$scan_mode){
$full_search = 0;
}
if ($full_search){
$rslt_sat = lockToSatellite($min_strength, $DishAngle, $wnd_az, $wnd_el, $scan_step);
if ($dbg_file !== null) {
fprintf($dbg_file, "lockToSatellite --> %s\n", print_r($rslt_sat,1));
}
$xml = new SimpleXMLElement("<?xml version='1.0'?><motosat/>");
$State = $xml_state->State+0; // 1 - Ready, 2 - Busy, 3 - Stow! (turned to stow by no reason?)
$busy = ($State & 2) != 0;
$SignalQuality = myfval(explode(",",$xml_state->SignalQuality)[0]);
$xml->addChild ('SignalQuality',(string) $SignalQuality );
$xml->addChild ('DishAngle',$xml_state->DishAngle );
$xml->addChild ('DishCount',$xml_state->DishCountt );
$xml->addChild ('busy',(string) $busy );
$xml->addChild ('State',(string) $State );
$xml->addChild ('Result',(string) print_r($rslt_sat,1));
$rslt=$xml->asXML();
header("Content-Type: text/xml");
header("Content-Length: ".strlen($rslt)."\n");
header("Pragma: no-cache\n");
// allow CORS: needed for multicam controls
header('Access-Control-Allow-Origin: *');
printf($rslt);
exit (0);
}
if ($scan_mode){
$xml_state = scan_window($min_strength, $DishAngle, $wnd_az, $wnd_el, $scan_step);
$Success = $xml_state->Success;
if (intval ($Success)){
$rslt = peakAzimuthOrElevation($xml_state, 0, $AZ_PLAY,$AZ_RESCAN, $AZ_RESCAN_STEP, $USABLE_FRACT, $USABLE_POW, $ARGMAX_OURSIDE);
$Success = ($rslt === 1)? 1 : 0;
$xml_state = simplexml_load_file($motosat_url);
if (intval ($Success)){
$rslt = peakAzimuthOrElevation($xml_state, 1, $EL_PLAY,$EL_RESCAN, $EL_RESCAN_STEP, $USABLE_FRACT, $USABLE_POW, $ARGMAX_OURSIDE);
$Success = ($rslt === 1)? 1 : 0;
$xml_state = simplexml_load_file($motosat_url);
$DishAngle1D = $xml_state->DishAngle;
if (intval ($Success) && $ADJUST_2D){
$Success = peak2D($xml_state, $AZ_PLAY, $EL_PLAY, $AZ_2D_RANGE, $EL_2D_RANGE, $AZ_2D_STEP, $EL_2D_STEP, $USABLE_FRACT, $USABLE_POW, $ARGMAX_OURSIDE_2D);
$xml_state = simplexml_load_file($motosat_url);
if ($Success){
$DishAngle2D = $xml_state->DishAngle;
}
}
}
}
$xml = new SimpleXMLElement("<?xml version='1.0'?><motosat/>");
$State = $xml_state->State+0; // 1 - Ready, 2 - Busy
$busy = ($State & 2) != 0;
$SignalQuality = myfval(explode(",",$xml_state->SignalQuality)[0]);
$xml->addChild ('Success',(string) $Success );
$xml->addChild ('SignalQuality',(string) $SignalQuality );
if (isset($DishAngle1D)){
$xml->addChild ('DishAngle1D',$DishAngle1D );
}
if (isset($DishAngle2D)){
$xml->addChild ('DishAngle2D',$DishAngle2D );
}
$xml->addChild ('DishAngle',$xml_state->DishAngle );
$xml->addChild ('DishCount',$xml_state->DishCountt );
$xml->addChild ('busy',(string) $busy );
$xml->addChild ('State',(string) $State );
$rslt=$xml->asXML();
header("Content-Type: text/xml");
header("Content-Length: ".strlen($rslt)."\n");
header("Pragma: no-cache\n");
// allow CORS: needed for multicam controls
header('Access-Control-Allow-Origin: *');
printf($rslt);
exit (0);
}
// Just move where requested
$total_cycles = 0;
$total_cycles = moveElAzSk_degrees($DishAngle, $multi);
$xml = new SimpleXMLElement("<?xml version='1.0'?><motosat/>");
$xml->addChild ('cycles',(string) $total_cycles );
$rslt=$xml->asXML();
header("Content-Type: text/xml");
header("Content-Length: ".strlen($rslt)."\n");
header("Pragma: no-cache\n");
// allow CORS: needed for multicam controls
header('Access-Control-Allow-Origin: *');
printf($rslt);
exit (0);
function lockToSatellite($min_strength, $DishAngle, $wnd_az, $wnd_el, $scan_step)
{
global $motosat_url, $dbg_file, $SAT_AZ_STEP, $GUARD_AZIMUTH, $GUARD_STEP, $AZ_TOL, $MAX_ARC_TILT;
global $AZ_PLAY, $AZ_RESCAN, $AZ_RESCAN_STEP, $USABLE_FRACT, $USABLE_POW, $ARGMAX_OURSIDE;
global $EL_PLAY,$EL_RESCAN, $EL_RESCAN_STEP, $HUGHES_THRESHOLD, $ADJUST_2D;
global $AZ_2D_RANGE, $EL_2D_RANGE, $AZ_2D_STEP, $EL_2D_STEP, $ARGMAX_OURSIDE_2D;
$xml_state = simplexml_load_file($motosat_url);
$DishAngleCenter = getDishAngles ($xml_state); // will go there if failed
$DishAngleCenter[0] = $DishAngle[0];
$DishAngleCenter[1] = $DishAngle[1];
$empty_az = array(); // array of pairs: ('low'=>min, "high"=>max) for scanned empoty azimuths in degrees
$satellites =array();// array of ('az'=>az, "el"=> el, 'strength'-> strength, 'guard_low', 'guard_high') in degrees for each found satellite
$num_az_steps = (int) ceil ($wnd_az/$SAT_AZ_STEP);
$az_min = $DishAngle[0] - $wnd_az/2;
if ($dbg_file !== null) {
fprintf($dbg_file, "+++++ lockToSatellite( %f, %s, %f, %f, %f\n",
$min_strength, print_r($DishAngle,1), $wnd_az, $wnd_el, $scan_step);
}
// $az_max = $az_min + ($num_az_steps)* $SAT_AZ_STEP;
while (true) { // loop until found correct satellite, or failed
$az_array = array_fill(0, $num_az_steps + 1, 0);
// mark already scanned emty ranges
foreach ($empty_az as $range){
$i_min = (int) ceil (($range['low'] - $az_min)/$SAT_AZ_STEP);
$i_max = (int) floor(($range['high'] - $az_min)/$SAT_AZ_STEP);
if ($i_min < 0) $i_min = 0;
if ($i_max > $num_az_steps) $i_max = $num_az_steps;
for ($i = $i_min; $i <= $i_max; $i++){
$az_array[$i] = -1;
}
}
if ($dbg_file !== null) {
fprintf($dbg_file, "0. az_array= %s\n", str_replace("\n"," ",print_r($az_array,1))."\n");
}
// Exclude each satellite with its guard range
foreach ($satellites as $indx => $azels){
$i_min = (int) round (($azels['az'] - $az_min - $azels['guard_low'])/$SAT_AZ_STEP);
$i_max = (int) round (($azels['az'] - $az_min + $azels['guard_high'])/$SAT_AZ_STEP);
if ($dbg_file !== null) {
fprintf($dbg_file, "i_min = %d, i_max= %d\n", $i_min, $i_max);
}
if ($i_min < 0) $i_min = 0;
if ($i_max > $num_az_steps) $i_max = $num_az_steps;
for ($i = $i_min; $i <= $i_max; $i++){
$az_array[$i] = $indx +1; // number of satellite, starting from 1
if ($dbg_file !== null) {
fprintf($dbg_file, "%d: %d\n", $i,$az_array[$i]);
}
}
}
if ($dbg_file !== null) {
fprintf($dbg_file, "1. az_array= %s\n", str_replace("\n"," ",print_r($az_array,1))."\n");
}
// Find azimuth range to scan
for ($i_low = 0; ($i_low <= $num_az_steps) && ($az_array[$i_low] != 0); $i_low++ );
if ($i_low > $num_az_steps) { // all searched, no luck
// Here is te exit from the loop on failure!
return array ('satellite' => null, 'satellites' => $satellites, 'empty' => $empty_az);
}
for ($i_high = $i_low; ($i_high < $num_az_steps) && ($az_array[$i_high+1] == 0); $i_high++);
// setup new scan range
$az_low = $az_min + $i_low * $SAT_AZ_STEP;
$az_high = $az_min + $i_high * $SAT_AZ_STEP;
$low_end_sat = ($i_low > 0)? $az_array[$i_low - 1] : -1;
$high_end_sat = ($i_high < $num_az_steps)? $az_array[$i_high + 1] : -1;
$az_range = $az_high - $az_low;
$az_center = ($az_high + $az_low) / 2;
if ($dbg_file !== null) {
fprintf($dbg_file, "DishAngleCenter=".str_replace("\n"," ",print_r($DishAngleCenter,1))."\n");
fprintf($dbg_file, "low_end_sat = %d, high_end_sat= %d\n",$low_end_sat,$high_end_sat);
fprintf($dbg_file, "Satellites=".str_replace("\n"," ",print_r($satellites,1))."\n");
}
if ($low_end_sat < 0){
if ($high_end_sat < 0) { // both ends unknown
$el_center = $DishAngleCenter[1];
$el_range = $wnd_el;
if ($dbg_file !== null) {
fprintf($dbg_file, "1: el_center = %f, el_range= %f\n",$el_center,$el_range);
}
} else { // satellite on the right only
$el_center = $satellites[$high_end_sat -1]['el'];
$el_range = $MAX_ARC_TILT * $az_range;
if ($dbg_file !== null) {
fprintf($dbg_file, "2: el_center = %f, el_range= %f\n",$el_center,$el_range);
}
}
} else {
if ($high_end_sat < 0) {// satellite on the left only
$el_center = $satellites[$low_end_sat -1]['el'];
$el_range = $MAX_ARC_TILT * $az_range;
if ($dbg_file !== null) {
fprintf($dbg_file, "3: el_center = %f, el_range= %f\n",$el_center,$el_range);
}
} else { // both ends have satellites
$el_center = ($satellites[$high_end_sat -1]['el'] + $satellites[$low_end_sat -1]['el']) / 2 ;
$el_range = abs($satellites[$high_end_sat -1]['el'] - $satellites[$low_end_sat -1]['el']);
if ($dbg_file !== null) {
fprintf($dbg_file, "4: el_center = %f, el_range= %f\n",$el_center,$el_range);
}
}
}
if ($el_center < 50){
return array ('satellite' => null, 'satellites' => $satellites, 'empty' => $empty_az);
}
// Do scanning of the range
if ($dbg_file !== null) {
fprintf($dbg_file, "==== Scanning sky window : center (az:%f7.3 el:%f7.3) az_range=%f7.3, el_range = %f7.3 ====\n",
$az_center, $el_center, $az_range, $el_range);
}
$xml_state = simplexml_load_file($motosat_url);
$DishAnglesScan = getDishAngles ($xml_state); // will go there if failed
$DishAnglesScan[0] = $az_center;
$DishAnglesScan[1] = $el_center;
$xml_state = scan_window($min_strength, $DishAnglesScan, $az_range, $el_range, $scan_step);
$success = intval ($xml_state->Success);
if (!$success) {
// $empty_az = array(); // array of pairs: ('low'=>min, "high"=>max) for scanned empoty azimuths in degrees
$empty_az[] = array('low'=> $az_low, 'high' => $az_high);
if ($dbg_file !== null) {
fprintf($dbg_file, ">>>>> Failed to find any satellites in the window : center (az:%f7.3 el:%f7.3) az_range=%f7.3, el_range = %f7.3 >>>>>\n",
$az_center, $el_center, $az_range, $el_range);
}
continue; // to next azimuth range
}
// Did found some satellite - peak azimuth
// peakAzimuthOrElevation - limit range to scan range, do not allow max to be outside of the scan range!
$minmax = array($az_low, $az_high);
if ($dbg_file !== null) {
fprintf($dbg_file, "Starting peakAzimuthOrElevation(...(%f, %f))\n",$az_low,$az_high);
}
$rslt_az = peakAzimuthOrElevation($xml_state, 0, $AZ_PLAY, $AZ_RESCAN, $AZ_RESCAN_STEP, $USABLE_FRACT, $USABLE_POW, $ARGMAX_OURSIDE, $minmax);
if ($dbg_file !== null) {
fprintf($dbg_file, "peakAzimuthOrElevation(...(%f, %f)) returned: %s\n",$az_low,$az_high, (string) $rslt_az);
}
$success_az = ($rslt_az ===1) ? 1 : 0;
$xml_state = simplexml_load_file($motosat_url);
$DishAnglesPeakAz = getDishAngles ($xml_state); // after peaking azimuth
$az_sat = $DishAnglesPeakAz[0];
if (!$success_az){ // what could be wrong here? tried to peak on existing satellite but was prohibited to go outside of the range?
if ($dbg_file !== null) {
fprintf($dbg_file, "**** Failed peaking azimuth - assuming that the peak was outside of the scan range, belonging to other satellite\n");
fprintf($dbg_file, "Peaking error: %s\n", $rslt_az);
// fprintf($dbg_file, "For now will only try to recover if the end of scan range was a satellite found before\n");
}
if (($low_end_sat > 0) && (($rslt_az == 'first element') || ($rslt_az == 'too low'))){
$sat = $satellites[$low_end_sat - 1];
if (($az_sat - $sat['az']) < $AZ_TOL + $AZ_RESCAN_STEP){ // accepting larger tolerance
$satellites[$indx]['guard_high'] += $GUARD_STEP; // search range was on the right, increasing high guard range for the satellite
if ($dbg_file !== null) {
fprintf($dbg_file, "**** Increasing high guard range of the satellite :\n".print_r($satellites[$indx],1));
}
continue;
}
}
if ((high_end_sat > 0) && (($rslt_az == 'last element') || ($rslt_az == 'too high'))){
$sat = $satellites[$high_end_sat - 1];
if (($sat['az'] - $az_sat) < $AZ_TOL + $AZ_RESCAN_STEP){ // accepting larger tolerance
$satellites[$indx]['guard_low'] += $GUARD_STEP; // search range was on the left, increasing low guard range for the satellite
if ($dbg_file !== null) {
fprintf($dbg_file, "**** Increasing low guard range of the satellite :\n".print_r($satellites[$indx],1));
}
continue;
}
}
// other errors - for now discarding that range completely
if ($dbg_file !== null) {
fprintf($dbg_file, "**** Other azimuth peaking errors(%s), discarding last search range %f7.3 < %f7.3\n",
$rslt_az, $az_low, $az_high);
}
$empty_az[] = array($az_low, $az_high);
continue;
}
// compare azimuth to already known satellites
foreach ($satellites as $indx => $sat){
if (abs($az_sat - $sat['az']) < $AZ_TOL){ // it is the same satellite as already found
if ($az_center < $sat['az']) {
$satellites[$indx]['guard_low'] += $GUARD_STEP; // search range was on the left, increasing low guard range for the satellite
if ($dbg_file !== null) {
fprintf($dbg_file, "**** Increasing low guard range of the satellite:\n".print_r($satellites[$indx],1));
}
} else {
$satellites[$indx]['guard_high'] += $GUARD_STEP;// search range was on the right, increasing high guard range for the satellite
if ($dbg_file !== null) {
fprintf($dbg_file, "**** Increasing high guard range of the satellite:\n".print_r($satellites[$indx],1));
}
}
continue; // recalculate azimuth range, try again
}
}
// got new satellite, peak elevation
$rslt_el = peakAzimuthOrElevation($xml_state, 1, $EL_PLAY,$EL_RESCAN, $EL_RESCAN_STEP, $USABLE_FRACT, $USABLE_POW, $ARGMAX_OURSIDE);
$Success_el = ($rslt_el === 1)? 1 : 0;
if ($dbg_file !== null) {
fprintf($dbg_file, "**** Peak elevation success = %d\n",$Success_el);
if (!$Success_el){
fprintf($dbg_file, "**** Peak elevation error: %s\n",$rslt_el);
}
}
$modem_strength = getModemStrength();
$xml_state = simplexml_load_file($motosat_url);
$DishAngleSat = getDishAngles($xml_state); // ->DishAngle;
$satellite = array(
'az' => $DishAngleSat[0],
"el" => $DishAngleSat[1],
'strength' => $modem_strength,
'guard_low' => $GUARD_AZIMUTH,
'guard_high' => $GUARD_AZIMUTH
);
if ($dbg_file !== null) {
fprintf($dbg_file, "**** Got a satellite\n".print_r($satellite, 1));
}
// See if it is Hughes modem
if ($modem_strength < $HUGHES_THRESHOLD){
if ($dbg_file !== null) {
fprintf($dbg_file, "**** Satellite modem strength is too low (%f < %f) not a target satellite, continuing search\n",$modem_strength, $HUGHES_THRESHOLD);
}
$satellites[] = $satellite;
continue;
}
if ($dbg_file !== null) {
fprintf($dbg_file, "**** Found target satellite, modem strength is %f >= %f\n",$modem_strength, $HUGHES_THRESHOLD);
}
if ($ADJUST_2D){
if ($dbg_file !== null) {
fprintf($dbg_file, "**** 2D peaking requested, performing it\n");
}
$rslt_2d = peak2D($xml_state, $AZ_PLAY, $EL_PLAY, $AZ_2D_RANGE, $EL_2D_RANGE, $AZ_2D_STEP, $EL_2D_STEP, $USABLE_FRACT, $USABLE_POW, $ARGMAX_OURSIDE_2D);
$Success_2d = $rslt_2d;
$xml_state = simplexml_load_file($motosat_url);
if ($dbg_file !== null) {
fprintf($dbg_file, "**** 2D peaking returned: ".$rslt_2d."\n");
}
if ($Success_2d){
$modem_strength = getModemStrength();
$xml_state = simplexml_load_file($motosat_url);
$DishAngleSat = getDishAngles($xml_state); // ->DishAngle;
$satellite = array(
'az' => $DishAngleSat[0],
"el" => $DishAngleSat[1],
'strength' => $modem_strength,
'guard_low' => $GUARD_AZIMUTH,
'guard_high' => $GUARD_AZIMUTH
);
}
$satellites[] = $satellite;
return array ('satellite' => $satellite, 'satellites' => $satellites, 'empty' => $empty_az);
}
}
}
function peak2D($xml_state, $az_play, $el_play, $az_range, $el_range, $az_step, $el_step, $fract, $pow = 1.0, $argmax_outside=0.0){
global $motosat_url, $dbg_file;
if ($xml_state === null){
$xml_state = simplexml_load_file($motosat_url);
}
$DishAngle = getDishAngles ($xml_state);
$azel_start_center = $DishAngle;
//move to sart rescan azimuth minus mechanical play
$DishAngle[0] = $azel_start_center[0] - $az_play - $az_range/2;
$DishAngle[1] = $azel_start_center[1] - $el_play - $el_range/2;
moveElAzSk_degrees($DishAngle);
$scan_strengths = Array();
for ($el = $azel_start_center[1] - $el_range / 2; $el < ($azel_start_center[1] + $el_range / 2 + $el_step); $el += $el_step) {
$scan_strengths_line = Array();
$DishAngle[1] = $el;
$DishAngle[0] = $azel_start_center[0] - $az_play - $az_range/2;
if ($dbg_file !== null) {
fprintf($dbg_file, "==== 2D scan line, elevation = %f ====\n",$el);
// fprintf($dbg_file, print_r($scan_strengths, 1));
}
moveElAzSk_degrees($DishAngle);
for ($az = $azel_start_center[0] - $az_range / 2; $az < ($azel_start_center[0] + $az_range / 2 + $az_step); $az += $az_step) {
$DishAngle[0] = $az;
moveElAzSk_degrees($DishAngle); // to be on the safe side re-read xml
$modem_strength = getModemStrength();
$scan_strengths_line[] = $modem_strength;
}
$scan_strengths[] = $scan_strengths_line;
}
if ($dbg_file !== null) {
fprintf($dbg_file, "==== 2D scan strengths (will be printed in findMax2d() ): ====\n");
// fprintf($dbg_file, print_r($scan_strengths, 1));
}
// $rel_argmax = findMax1d($scan_strengths, $fract, $pow, $argmax_outside);
$rel_argmax = findMax2d($scan_strengths, $fract, $pow, $argmax_outside); // $pow not yet used
$azel_argmax = $azel_start_center;
$success = 0;
if ($rel_argmax !== null) {
$azel_argmax = array(
$azel_start_center[0] - $az_range / 2 + $az_step * $rel_argmax[0],
$azel_start_center[1] - $el_range / 2 + $el_step * $rel_argmax[1]
);
$success = 1;
} else {
if ($dbg_file !== null) {
fprintf($dbg_file, "****** Failed to find maximum for 2d peaking, going to known position.\n");
}
}
if ($dbg_file !== null) {
fprintf($dbg_file, "relative argmax = [az=%f, el=%f]\n", $rel_argmax[0], $rel_argmax[1]);
fprintf($dbg_file, " argmax = [az=%f, el=%f] (was [az=%f, el=%f])\n", $azel_argmax[0], $azel_argmax[1], $azel_start_center[0], $azel_start_center[1]);
}
$DishAngle[0] = $azel_argmax[0] - $az_play;
$DishAngle[1] = $azel_argmax[1] - $el_play;
if ($dbg_file !== null) {
fprintf($dbg_file, "====== Moving to compensate az/el motors play to [az=%f, el=%f]\n", $DishAngle[0], $DishAngle[1]);
}
moveElAzSk_degrees($DishAngle);
$DishAngle[0] = $azel_argmax[0];
$DishAngle[1] = $azel_argmax[1];
if ($dbg_file !== null) {
fprintf($dbg_file, "====== Moving to argmax position = [az=%f, el=%f]\n", $DishAngle[0], $DishAngle[1]);
}
moveElAzSk_degrees($DishAngle);
return $success; // success
}
// return ===1 if OK, else error text string from findMax1D
function peakAzimuthOrElevation($xml_state, $el_not_az, $azel_play, $azel_range, $azel_step, $fract, $pow = 1.0, $argmax_outside = 0.2, $minmax=null)
{
global $motosat_url, $dbg_file;
if ($xml_state === null) {
$xml_state = simplexml_load_file($motosat_url);
}
$DishAngle = getDishAngles($xml_state);
$motor = $el_not_az ? 1 : 0;
$direction = $el_not_az ? "ELEVATION" : "AZIMUTH";
$azel_start_center = $DishAngle[$motor];
// move to sart rescan azimuth minus mechanical play
$DishAngle[$motor] = $azel_start_center - $azel_play - $azel_range / 2;
moveElAzSk_degrees($DishAngle);
$scan_strengths = Array();
$azel_min = $azel_start_center - $azel_range / 2;
$azel_max = $azel_start_center + $azel_range / 2 + $azel_step;
if ($minmax !== null) {
if ($azel_min < $minmax[0]){
$azel_min = $minmax[0];
}
if ($azel_max > $minmax[1]){
$azel_max = $minmax[1];
}
}
if ($dbg_file !== null) {
fprintf($dbg_file, "Peaking %s\n",$direction);
}
if (($azel_max - $azel_min) < $azel_step){
if ($dbg_file !== null) {
fprintf($dbg_file, "==== $direction scan range to small min = %f, max = %f: ====\n", $azel_min, $azel_max);
}
return 'small range';
}
if (($azel_max - $azel_min) < 2.01 * $azel_step){
$azel_step = ($azel_max - $azel_min) / 2.01; // at least 3 samples
if ($dbg_file !== null) {
fprintf($dbg_file, "==== $direction scan range to small min = %f, max = %f new step = %f: ====\n", $azel_min, $azel_step);
}
}
for ($azel = $azel_min; $azel < $azel_max; $azel += $azel_step) {
$DishAngle[$motor] = $azel;
moveElAzSk_degrees($DishAngle); // to be on the safe side re-read xml
$modem_strength = getModemStrength();
$scan_strengths[] = $modem_strength;
}
if ($dbg_file !== null) {
fprintf($dbg_file, "==== $direction scan strengths: ====\n");
fprintf($dbg_file, print_r($scan_strengths, 1));
}
// $rel_argmax = findMax1d($scan_strengths, $fract, $pow, $argmax_outside);
$rslt = findMax1d($scan_strengths, $fract, $pow, $argmax_outside);
$rel_argmax = $rslt['argmax'];
if (isset($rslt['err'])){
if ($dbg_file !== null) {
fprintf($dbg_file, "****** Failed to find maximum for $direction, going to known position.\n");
}
}
$azel_argmax = $azel_min + $azel_step * $rel_argmax;
if ($dbg_file !== null) {
fprintf($dbg_file, "relative argmax = %f\n", $rel_argmax);
fprintf($dbg_file, "$direction argmax = %f (was %f)\n", $azel_argmax, $azel_start_center);
}
$DishAngle[$motor] = $azel_argmax - $azel_play;
if ($dbg_file !== null) {
fprintf($dbg_file, "====== Moving $direction to compensate motor play to = %f\n", $DishAngle[$motor]);
}
moveElAzSk_degrees($DishAngle);
$DishAngle[$motor] = $azel_argmax;
if ($dbg_file !== null) {
fprintf($dbg_file, "====== Moving $direction to argmax position = %f\n", $DishAngle[$motor]);
}
moveElAzSk_degrees($DishAngle);
if (isset($rslt['err'])){
return $rslt['err'];
}
return 1; // success
}
function findMax2d($data, $fract, $pow, $frac_outside = 0.2){ // $pow not yet used
global $HUGHES_BAD_STRENGTHS, $dbg_file;
$min= $data[0][0];
$max = $data[0][0];
$rows = sizeof($data);
$cols = sizeof($data[0]); // should be rectangular
$argmax = array(0.0, 0.0);
foreach ($data as $row => $line) {
foreach ($line as $col => $v) {
if ($v > $max) {
$max = $v;
$argmax = array($col, $row,);
} else if ($v < $min)
$min = $v;
}
}
$threshold = $min + ($max-$min)*$fract;
// Find a 2D cluster around $argmax exceeding $threshold
$cluster = $data;
for ($i = 0; $i < $rows; $i++){
for ($j = 0; $j < $cols; $j++){
$cluster[$i][$j] = false;
}
}
// Wve method (1 directions)
$poly_data = array();
$queue = array();
$xy = $argmax; // x,y pair
// put a cell into a queue, in $poly_data and mark a cell as used
$queue[] = $xy;
if (! in_array($data[$xy[1]][$xy[0]], $HUGHES_BAD_STRENGTHS)) {
$poly_data[] = array(
array(
0.0,
0.0
), // $xy,
array(
$data[$xy[1]][$xy[0]]
)
);
}
$cluster[$xy[1]][$xy[0]] = true;
while (sizeof($queue) > 0) {
$xy0 = $queue[0];
$queue = array_slice($queue, 1);
// print("<=" . print_r($xy0, 1));
for ($dir = 0; $dir < 4; $dir ++) {
$xy = $xy0;
switch ($dir) {
case 0:
$xy[0] ++;
if ($xy[0] >= $cols) {
continue;
}
// print($dir . ":" . print_r($xy, 1));
break;
case 1:
$xy[1] ++;
if ($xy[1] >= $rows) {
continue;
}
// print($dir . ":" . print_r($xy, 1));
break;
case 2:
$xy[0] --;
if ($xy[0] < 0) {
continue;
}
// print($dir . ":" . print_r($xy, 1));
break;
case 3:
$xy[1] --;
if ($xy[1] < 0) {
continue;
}
// print($dir . ":" . print_r($xy, 1));
break;
}
if ($cluster[$xy[1]][$xy[0]])
continue; // already used
if ($data[$xy[1]][$xy[0]] < $threshold) // signal too weak
continue; // already used
$queue[] = $xy;
$cluster[$xy[1]][$xy[0]] = true;
if (! in_array($data[$xy[1]][$xy[0]], $HUGHES_BAD_STRENGTHS)) { // use for the wave, but do not use for polynimial maximum
$poly_data[] = array(
array(
$xy[0] - $argmax[0],
$xy[1] - $argmax[1]
),
array(
$data[$xy[1]][$xy[0]]
)
);
}
}
}
if ($dbg_file !== null) {
fprintf($dbg_file, "*** sizeof(poly_data)=".sizeof($poly_data)."\n");
}
// print ("*** sizeof(poly_data)=".sizeof($poly_data)."\n");
if ($dbg_file !== null) {
fprintf($dbg_file,"argmax= (x=%d ,y=%d), max = %f, threshold = %f\n",
$argmax[0], $argmax[1], $max, $threshold);
for ($i = 0; $i < $rows; $i ++) {
for ($j = 0; $j < $cols; $j ++) {
if (($i==$argmax[1]) && ($j==$argmax[0])) {
fprintf($dbg_file,"[%02d]", $data[$i][$j]);
} else if ($cluster[$i][$j] > 0) {
fprintf($dbg_file,"<%02d>", $data[$i][$j]);
} else {
fprintf($dbg_file," %02d ", $data[$i][$j]);
}
}
fprintf($dbg_file,"\n");
}
}
$pa = new PolynomialApproximation();
$pa->debugLevel = 1;
$pa->debugFile = $dbg_file;
$rslt = $pa->quadraticMax2d($poly_data);
if ($rslt == null){
return null;
}
$rslt_dbg =$rslt;
$rslt[0] += $argmax[0];
$rslt[1] += $argmax[1];
if ($dbg_file) {
fprintf($dbg_file, "argmax= (x=%d ,y=%d), max = %f, threshold = %f, rslt_dbg=(x=%f, y=%f), rslt=(x=%f, y=%f)\n",
$argmax[0], $argmax[1], $max, $threshold,$rslt_dbg[0],$rslt_dbg[1],$rslt[0],$rslt[1]);
fprintf($dbg_file, print_r($rslt,1));
}
if (is_nan($rslt[0]) || is_nan($rslt[1])){
if ($dbg_file) {
fprintf($dbg_file, "Could not find maximum (NaN): coeff = \n".print_r($rslt,1)."\n");
}
return null; // no maximum
}
if ($rslt[0] < -($frac_outside * $cols)){
if ($dbg_file) {
fprintf($dbg_file, "argmax[0] is too low = %f, range=%d\n",$rslt[0],$cols );
}
return null; // az too low
}
if ($rslt[0] > ((1.0 + $frac_outside) * $cols)){
if ($dbg_file) {
fprintf($dbg_file, "argmax[0] is too high = %f, range=%d\n",$rslt[0],$cols );
}
return null; // too low
}
if ($rslt[1] < -($frac_outside * $rows)){
if ($dbg_file) {
fprintf($dbg_file, "argmax[1] is too low = %f, range=%d\n",$rslt[1],$rows );
}
return null; // az too low
}
if ($rslt[1] > ((1.0 + $frac_outside) * $rows)){
if ($dbg_file) {
fprintf($dbg_file, "argmax[1] is too high = %f, range=%d\n",$rslt[1],$cols );
}
return null; // too low
}
return $rslt; // $rslt;
}
function findMax1d($data, $fract, $pow, $frac_outside = 0.2){
global $HUGHES_BAD_STRENGTHS, $dbg_file;
$min= $data[0];
$max = $data[0];
$argmax = 0;
foreach ($data as $k => $v) {
if (! in_array($v, $HUGHES_BAD_STRENGTHS)) {
if ($v > $max) {
$max = $v;
$argmax = $k;
} else if ($v < $min) {
$min = $v;
}
}
}
if ($argmax == 0){
return array('argmax'=>$argmax,'err'=>'first element');
}
if ($argmax >= (sizeof($data) -1)){
return array('argmax'=>$argmax,'err'=>'last element');
}
// ignoring bad strengths (==30) - they will be filtered later
$threshold = $min + ($max-$min) * $fract;
$k_min = $argmax;
while (($k_min > 0) && ($data[$k_min - 1] >= $threshold)){
$k_min--;
}
$k_max = $argmax;
$last = sizeof($data) - 1;
while (($k_max < $last) && ($data[$k_max + 1] >= $threshold)){
$k_max++;
}
$datap = array_fill(0, sizeof($data),0);
for ($k = $k_min; $k <= $k_max; $k++){
$datap[$k] = $max - pow($max - $data[$k], $pow);
}
$poly_data = Array();
for ($k = $k_min; $k <= $k_max; $k++){
if (! in_array($datap[$k], $HUGHES_BAD_STRENGTHS)) { // skip samples with "bad" strengths (see explanation in the $HUGHES_BAD_STRENGTHS declaration
$poly_data[] = Array(
$k - $argmax,
$datap[$k]
);
}
}
$pa = new PolynomialApproximation();
$pa->debugLevel = 1;
$pa->debugFile = $dbg_file;
$rslt = $pa->polynomialApproximation1d($poly_data, 2);
if ($dbg_file) {
fprintf($dbg_file, "argmax= %d , k_min= %d, k_max = %d, max = %f, threshold = %f, rslt:\n",
$argmax, $k_min, $k_max, $max, $threshold);
fprintf($dbg_file, print_r($rslt,1));
$pre = array_fill(0, sizeof($data),0);
$diff= array_fill(0, sizeof($data),0);
for ($k = $k_min; $k <= $k_max; $k++){
$x = $k-$argmax;
$pre[$k]=$rslt[0]+$rslt[1]*$x+$rslt[2]*$x*$x;
$diff[$k]=$pre[$k]-$datap[$k];
}
for ($k = $k_min; $k <= $k_max; $k++){
fprintf($dbg_file, "[%02d]: %8.3f %8.3f %8.3f %8.3f\n", $k, $data[$k], $datap[$k], $pre[$k], $diff[$k]);
}
fprintf($dbg_file, "poly_data= \n".print_r($poly_data,1)."\n");
}
if (is_nan($rslt[0]) || is_nan($rslt[1]) || is_nan($rslt[2])){
if ($dbg_file) {
fprintf($dbg_file, "Could not find maximum (NaN): coeff = \n".print_r($rslt,1)."\n");
}
return array('argmax'=>$argmax,'err'=>'NaN coefficients');
}
if ($rslt[2] >= 0){
if ($dbg_file) {
fprintf($dbg_file, "Could not find maximum coeff = \n".print_r($rslt,1)."\n");
}
return array('argmax'=>$argmax,'err'=>'a2 >= 0');
}
$rel_argmax = $argmax - $rslt[1] / (2 * $rslt[2]);
if ($rel_argmax < -($frac_outside * sizeof($data))){
if ($dbg_file) {
fprintf($dbg_file, "argmax is too low = %f, range=%d\n",$rel_argmax,sizeof($data) );
}
return array('argmax'=>$rel_argmax,'err'=>'too low');
}
if ($rel_argmax > ((1.0 + $frac_outside) * sizeof($data))){
if ($dbg_file) {
fprintf($dbg_file, "argmax is too high = %f, range=%d\n",$rel_argmax,sizeof($data) );
}
return array('argmax'=>$rel_argmax,'err'=>'too high');
}
return array('argmax'=>$rel_argmax,'err'=>null); // $rslt;
}
/**
* Scan rectangular AZ/EL window arownd expected satellite position, alternating
* azimuth directions and increasing elevation offset.
* Start with expected elevation and low az margin, scan azimuth to high margin,
* then alternatively increase/decrease elevation
* @param $threshold - minimal modem signal strength
* @param $DishAngleCenter - array of (elevation, azimuth, skew) in degrees,
* corresponding to the center of the scan window
* @param $wnd_az - full range of azimuth scan in degrees
* @param $wnd_el - full range of elevation scan in degrees
* @param $scan_step - elevation scan step
* @param $dir - 0: start scanning from right to left, 1 : first scan from left to right,
* null - determine direction automatically from the current azimuth
* @return SimpleXMLElement -
*/
function scan_window($threshold, $DishAngleCenter, $wnd_az, $wnd_el, $scan_step, $dir = null){
global $motosat_url,$LATE_STOP_AZ,$dbg_file;
if ($dir === null) {
$xml_state = simplexml_load_file($motosat_url);
$DishAnglesNow = getDishAngles($xml_state); // will go there if failed
$dir = ($DishAnglesNow[0] < $DishAngleCenter[0]) ? 1 : 0;
}
$DishAngle = Array($DishAngleCenter[0],$DishAngleCenter[1],$DishAngleCenter[2]);
for ($delta_el = 0.0; $delta_el < $wnd_el/2; $delta_el += $scan_step) {
$passes = ($delta_el > 0.0)? 2 : 1;
for ($pass = 0; $pass < $passes; $pass++) {
// for ($dir = 0; $dir < 2; $dir++) {
if ($dir > 0){
$DishAngle[1] = $DishAngleCenter[1] + $delta_el;
$az_start = $DishAngleCenter[0] + $wnd_az/2;
$az_end = $DishAngleCenter[0] - $wnd_az/2;
} else {
$DishAngle[1] = $DishAngleCenter[1] - $delta_el;
$az_start = $DishAngleCenter[0] - $wnd_az/2;
$az_end = $DishAngleCenter[0] + $wnd_az/2;
}
$DishAngle[0] = $az_start;
if ($dbg_file) {
fprintf($dbg_file, "\ndir=%d:\n",$dir);
fprintf($dbg_file, "wnd_az=%f:\n",$wnd_az);
fprintf($dbg_file, "wnd_el=%f:\n",$wnd_el);
fprintf($dbg_file, "threshold=%f:\n",$threshold);
fprintf($dbg_file, "scan_step=%f:\n",$scan_step);
fprintf($dbg_file, "DishAngle - start:\n");
fprintf($dbg_file, str_replace("\n"," ",print_r($DishAngle,1))."\n");
fprintf($dbg_file, "DishAngleCenter - start:\n");
fprintf($dbg_file, str_replace("\n"," ",print_r($DishAngleCenter,1))."\n");
}
// while (null !==moveElAzSk_degrees($DishAngle)); // returns number of steps
moveElAzSk_degrees($DishAngle); // returns number of steps
$DishAngle[0] = $az_end;
if ($dbg_file) {
fprintf($dbg_file, "\nDishAngle - end:\n");
fprintf($dbg_file, str_replace("\n"," ",print_r($DishAngle,1))."\n");
}
moveElAzSk_start_degrees($DishAngle);
$scan_rslt = waitMotorsReady($threshold);
if ($dbg_file) {
fprintf($dbg_file, "-----scan_rslt=%d:\n",$scan_rslt);
}
if ($scan_rslt < 0) {
$xml_state = simplexml_load_file($motosat_url);
if ($dbg_file) {
$DishAngle = getDishAngles ($xml_state);
fprintf($dbg_file, "\n***** DishAngle - after hitting/stopped:\n");
fprintf($dbg_file, str_replace("\n"," ",print_r($DishAngle,1))."\n");
}
//,$LATE_STOP_AZ
//move az back to compensate for late stop
$DishCount = getDishCounts($xml_state);
if ($dir > 0){
$DishCount[0] += $LATE_STOP_AZ;
} else {
$DishCount[0] -= $LATE_STOP_AZ;
}
moveElAzSk_counts($DishCount);
if ($dbg_file) {
$xml_state = simplexml_load_file($motosat_url);
$DishAngle = getDishAngles ($xml_state);
fprintf($dbg_file, "\nDishAngle - after backing:\n");
fprintf($dbg_file, str_replace("\n"," ",print_r($DishAngle,1))."\n");
}
$xml_state->addChild ('Success',(string) 1 );
return $xml_state;
}
}
$dir = 1 - $dir;
}
moveElAzSk_degrees($DishAngleCenter);
// while (null !==moveElAzSk_degrees($DishAngleCenter));
moveElAzSk_degrees($DishAngleCenter);
$xml_state = simplexml_load_file($motosat_url);
$xml_state->addChild ('Success',(string) 0 );
return $xml_state;
}
//<b>49</b>
//<b><font color=red>9</font></b>
function getModemStrength(){ //0.2sec
global $modem_strengt_url,$dbg_file;
$modem_page=file_get_contents($modem_strengt_url);
// $pstr="@<b>([^<]*)</b>@i";
$pstr="@<b>(<font[^>]*>)?([^<]*)</@i";
$matches=null; // just define
preg_match($pstr,$modem_page, $matches);
// return myfval($matches[1]);
return myfval($matches[2]);
}
function moveElAzSk_start_counts($new_azelsk_count) {
global $motosat_url, $AZ_CMAX, $EL_CMAX, $SK_CMAX,$OVERSHOOT,$dbg,$dbg_file;
$xml_state = simplexml_load_file($motosat_url);
$DishCount = getDishCounts($xml_state);
if ($DishCount[0] < 0) $DishCount[0] = 0;
if ($DishCount[1] < 0) $DishCount[1] = 0;
if ($DishCount[2] < 0) $DishCount[2] = 0;
if ($DishCount[0] > $AZ_CMAX) $DishCount[0] = $AZ_CMAX;
if ($DishCount[1] > $EL_CMAX) $DishCount[1] = $EL_CMAX;
if ($DishCount[2] > $SK_CMAX) $DishCount[2] = $SK_CMAX;
$dist_el = $new_azelsk_count[1] - $DishCount[1];
$dist_sk = $new_azelsk_count[2] - $DishCount[2];
$dist_az = $new_azelsk_count[0] - $DishCount[0];
if (abs ($dist_el) <= $OVERSHOOT) $dist_el = 0;
if (abs ($dist_sk) <= $OVERSHOOT) $dist_sk = 0;
if (abs ($dist_az) <= $OVERSHOOT) $dist_az = 0;
$dir = "Up";
$dist = 0;
/*
* $dist_el > 0 do it first, $dist_el < 0 - do it last
*/
// if ($dist_el != 0){
if ($dist_el > 0){
// moving elevation up first
$mode = "El";
$dist = $dist_el;
} else if ($dist_sk != 0){
// moving skew second
$mode = "Sk";
$dist = $dist_sk;
} else if ($dist_az != 0){
// moving azimuth third
$mode = "Az";
$dist = $dist_az;
} else if ($dist_el < 0){
// moving elevation down last
$mode = "El";
$dist = $dist_el;
}
if ($dist != 0){
if ($dist > 0){
$dir = "Up";
} else {
$dir = "Dn";
}
$dist = abs($dist);
$url = $motosat_url."?Action=".$mode.$dir.'&Distance='.$dist."&Units=0";
if ($dbg_file) {
fprintf($dbg_file, "moveElAzSk_start_counts(): url = %s:\n",$url);
}
if (false && $dbg_file) {
fprintf($dbg_file, "new_azelsk_count:\n");
fprintf($dbg_file, print_r($new_azelsk_count,1));
fprintf($dbg_file, "DishCount:\n");
fprintf($dbg_file, print_r($DishCount,1));
}
if ($dbg) {
echo "<!--";
var_dump($new_azelsk_count);
var_dump($DishCount);
var_dump($url);
$url = $motosat_url;
echo "-->";
}
$xml_state = simplexml_load_file($url);
return $xml_state;
}
return; // return null - no rotation is needed
}
function moveElAzSk_start_degrees($new_azelsk_degree) {
global $AZ_0, $EL_0, $SK_0, $AZ_CPD, $EL_CPD, $SK_CPD,$dbg,$dbg_file;
$new_azelsk_count = Array (
(int) round(($new_azelsk_degree[0] + $AZ_0)*$AZ_CPD),
(int) round(($new_azelsk_degree[1] + $EL_0)*$EL_CPD),
(int) round(($new_azelsk_degree[2] + $SK_0)*$SK_CPD));
if ($dbg_file) {
$new_azelsk_count_dbg = Array (
($new_azelsk_degree[0] + $AZ_0)*$AZ_CPD,
($new_azelsk_degree[1] + $EL_0)*$EL_CPD,
($new_azelsk_degree[2] + $SK_0)*$SK_CPD);
fprintf($dbg_file, ".... moveElAzSk_start_degrees(): new_azelsk_degree: ");
fprintf($dbg_file, str_replace("\n"," ",print_r($new_azelsk_degree,1))."\n");
// fprintf($dbg_file, "new_azelsk_count_dbg:\n");
// fprintf($dbg_file, print_r($new_azelsk_count_dbg,1));
// fprintf($dbg_file, "new_azelsk_count:\n");
// fprintf($dbg_file, print_r($new_azelsk_count,1));
}
if ($dbg) {
$new_azelsk_count_dbg = Array (
($new_azelsk_degree[0] + $AZ_0)*$AZ_CPD,
($new_azelsk_degree[1] + $EL_0)*$EL_CPD,
($new_azelsk_degree[2] + $SK_0)*$SK_CPD);
echo "<!--";
var_dump($new_azelsk_degree);
var_dump($new_azelsk_count_dbg);
var_dump($new_azelsk_count);
echo "-->";
}
return moveElAzSk_start_counts($new_azelsk_count);
}
/**
* Wait motors stopped and optionally modem strength > threshold
* Can be improved slightly by curl-multi: reading modem - 0.2s, controller - 0.29s
* @param $modem_threshold - if >0, stop on modem strength above threshold
* @return: 0: no movement needed, >0 - number of status requests, <0 - -SignalQuality
*/
function waitMotorsReady($modem_threshold = 0.0){ //
global $motosat_url,$dbg_file;
$busy = true;
$try = 0;
while ($busy) {
$xml_state = simplexml_load_file($motosat_url);
$State = $xml_state->State+0; // 1 - Ready, 2 - Busy
$busy = ($State & 2) != 0;
if ($modem_threshold > 0){
$SignalQuality = myfval(explode(",",$xml_state->SignalQuality)[0]);
if ($SignalQuality > $modem_threshold) {
$url = $motosat_url."?Action=Stop&Distance=0&Units=0";
$xml_state1 = simplexml_load_file($url);
if ($dbg_file) {
fprintf($dbg_file, "SignalQuality= %f:\n",$SignalQuality);
}
while ($busy) {
$xml_state1 = simplexml_load_file($motosat_url);
$State = $xml_state1->State+0; // 1 - Ready, 2 - Busy
$busy = ($State & 2) != 0;
if ($dbg_file) {
fprintf($dbg_file,$busy);
fprintf($dbg_file, " %03d State= %d:\n",$try,$State);
}
}
// Now move back to where good signal strength was detected
$DishCountGood = getDishCounts($xml_state);
moveElAzSk_counts($DishCountGood);
if ($dbg_file) {
fprintf($dbg_file, "SignalQuality= %f:\n",$SignalQuality);
}
return -$SignalQuality;
}
}
$try++;
if ($dbg_file) {
fprintf($dbg_file, "%03d State= %d:\n",$try,$State);
}
//?Action=Stop&Distance=0&Units=0
}
return $try;
}
function waitMotorsReadyScan($modem_threshold = 0.0){ //
global $motosat_url,$dbg_file;
$busy = true;
$try = 0;
$xml_states = array();
$stop_index = 0;
while ($busy) {
$xml_state = simplexml_load_file($motosat_url);
$xml_states[] = $xml_state;
$State = $xml_state->State+0; // 1 - Ready, 2 - Busy
$busy = ($State & 2) != 0;
if ($modem_threshold > 0){
$SignalQuality = myfval(explode(",",$xml_state->SignalQuality)[0]);
if ($SignalQuality > $modem_threshold) {
$stop_index = count($xml_states);
$url = $motosat_url."?Action=Stop&Distance=0&Units=0";
$xml_state1 = simplexml_load_file($url);
if ($dbg_file) {
fprintf($dbg_file, "SignalQuality= %f:\n",$SignalQuality);
}
$xml_states[] = $xml_state1;
while ($busy) {
$xml_state1 = simplexml_load_file($motosat_url);
$xml_states[] = $xml_state1;
$State = $xml_state1->State+0; // 1 - Ready, 2 - Busy
$busy = ($State & 2) != 0;
if ($dbg_file) {
fprintf($dbg_file,$busy);
fprintf($dbg_file, " %03d State= %d:\n",$try,$State);
}
}
// Now move back to where good signal strength was detected
$DishCountGood = getDishCounts($xml_state);
moveElAzSk_counts($DishCountGood);
if ($dbg_file) {
fprintf($dbg_file, "SignalQuality= %f:\n",$SignalQuality);
}
return -$SignalQuality;
}
}
$try++;
if ($dbg_file) {
fprintf($dbg_file, "%03d State= %d:\n",$try,$State);
}
//?Action=Stop&Distance=0&Units=0
}
return $try;
}
function moveElAzSk_counts($new_azelsk_count, $multi = true)
{
$total_cycles = 0;
while (true) {
$xml_state = moveElAzSk_start_counts($new_azelsk_count);
if (isset($xml_state)) {
$cycles = waitMotorsReady();
$total_cycles += $cycles;
if (!$multi)
return $total_cycles;
} else
return $total_cycles; // did not move last time
}
}
function moveElAzSk_degrees($new_azelsk_degree, $multi = true)
{
global $dbg_file;
$total_cycles = 0;
while (true) {
$xml_state = moveElAzSk_start_degrees($new_azelsk_degree);
if (isset($xml_state)) {
$cycles = waitMotorsReady();
$total_cycles += $cycles;
if (! $multi) {
if ($dbg_file) {
fprintf($dbg_file, "moveElAzSk_degrees(), multi=" . $multi . ", total_cycles=" . $total_cycles . "\n");
}
return $total_cycles;
}
} else {
if ($dbg_file) {
fprintf($dbg_file, "moveElAzSk_degrees(), multi=" . $multi . ", total_cycles=" . $total_cycles . ", xml_state is NOT set\n");
// fprintf($dbg_file, print_r(debug_backtrace(),1));
}
return $total_cycles; // did not move last time
}
}
}
function myval ($s) {
$s=trim($s,"\" ");
if (strtoupper(substr($s,0,2))=="0X") return intval(hexdec($s));
else return intval($s);
}
function myfval ($s) {
$s=trim($s,"\" ");
return floatval($s);
}
/**
* Get 3 dish angles (az/el/sk) in degrees from the XML data received from controller
* @param $xml_state : XML data from the controller
* @return: array of 3 angles (degrees): azimuth, elevation, skew
*/
function getDishAngles($xml_state){
$DishAngles = explode(",",$xml_state->DishAngle);
foreach ($DishAngles as $key => $value){
$DishAngles[$key] = floatval($value);
}
return $DishAngles;
}
/**
* Get 3 dish angles (az/el/sk) in counts from the XML data received from controller
* @param $xml_state : XML data from the controller
* @return: array of 3 angles (counts): azimuth, elevation, skew
*/
function getDishCounts($xml_state){
$DishCounts = explode(",",$xml_state->DishCount);
foreach ($DishCounts as $key => $value){
$DishCounts[$key] = floatval($value);
}
return $DishCounts;
}
function show_vars($names){
$txt="";
foreach ($names as $name){
// print ( $name." = ".print_r($GLOBALS[$name], 1)."\n");
$txt.= $name." = ".print_r($GLOBALS[$name], 1)."\n";
}
return $txt;
}
?>
\ 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