#!/usr/bin/perl -w ### /usr/bin/perl -wT # 22/08/2011 - Appears I got heading and roll reversed # fg_server_xml.cgi: for FGMap # fg_server_kml.cgi: initial request from GE # fg_server_kml.cgi and callsigns=: update request from GE # # TODO: callsigns is semicolon seperated, can be easily broken use strict; use warnings; use Time::gmtime; use IO::Socket; #use lib "./sg_perl/blib/lib"; #use lib "./sg_perl/blib/arch/auto/sgmath"; #use sgmath; #use Math::Trig qw(great_circle_distance great_circle_direction deg2rad rad2deg); use Math::Trig; my $SGD_PI = 3.1415926535; my $SGD_DEGREES_TO_RADIANS = $SGD_PI / 180.0; my $SGD_RADIANS_TO_DEGREES = 180.0 / $SGD_PI; my $SGD_MIN = 1.17549e-038; my $testing = 1; my $test_socket = 1; my $add_sg_math = 0; my ($LF); my $write_log = 1; my $PATH_SEP = "\\"; my $log_out = "templog.txt"; my $log_dir = 'C:\GTools\perl'; my $log_file = $log_dir.$PATH_SEP.$log_out; my $output_structure_value = 0; # add output to copy into a c++ module my ($HTTP_HOST, $SCRIPT_NAME, $QUERY_STRING, $DOCUMENT_PATH); #my $def_server = "localhost"; my $def_server = "mpserver14.flightgear.org"; my $port = 5001; my $in_callsigns = "GA9999"; my $act_server = $def_server; my(@last_callsigns); my(@this_callsigns); my $do_def_serv = 1; my $do_win7 = 1; my $do_all = 0; my $do_fgx = 0; my $do_dell01 = 0; my $do_dell02 = 0; my ($output) = ""; my ($l); my (%ocs); my @conversions = (); #/// Quaternion # x,y,z,w my $QX = 0; my $QY = 1; my $QZ = 2; my $QW = 3; #/// Vector(3) # x,y,z my $VX = 0; my $VY = 1; my $VZ = 2; sub prt($) { my $txt = shift; if ($write_log) { print $LF $txt; } print $txt; } sub test_conv(); sub fgs_rad2deg($) { my ($rad) = @_; return ($rad * $SGD_RADIANS_TO_DEGREES); } # 'mpserver01.flightgear.org (Germany)', my %server_location = ( 1 => 'Frankfurt/Germany', 2 => 'Kansas/USA / Hong Kong', 3 => 'Germany', 4 => 'UK', 5 => 'Texas US', 6 => 'Sweden', 7 => 'Wisconsin US', 8 => 'Germany', 9 => 'Germany', 10 => 'Montpellier, France', 11 => 'Vilnius, Lithuania', 12 => 'Amsterdam, Netherlands', 13 => 'Grenoble, France' ); sub get_YYYYMMDD_hhmmss_UTC { my ($t) = shift; # sec, min, hour, mday, mon, year, wday, yday, and isdst. my $tm = gmtime($t); my $m = sprintf( "%04d/%02d/%02d %02d:%02d:%02d", $tm->year() + 1900, $tm->mon() + 1, $tm->mday(), $tm->hour(), $tm->min(), $tm->sec()); return $m; } # ============================================================ # # SimGear Services, rendered in perl # ============================================================ # # dot(const SGVec3& v1, const SGVec3& v2) # { return v1(0)*v2(0) + v1(1)*v2(1) + v1(2)*v2(2); } # Given 2 Vectors3, return the dot product sub scalar_dot_product($$) { my ($rv1,$rv2) = @_; return ${$rv1}[0] * ${$rv2}[0] + ${$rv1}[1] * ${$rv2}[1] + ${$rv1}[2] * ${$rv2}[2]; } # The euclidean norm of the vector, that is what most people call length # norm(const SGVec3& v) # { return sqrt(dot(v, v)); } # Given a Vector3, return length sub norm_vector_length($) { my ($rv) = @_; return sqrt(scalar_dot_product($rv, $rv)); } # print out a quaternion - x,y,z,w sub show_quat($) { my ($rv4) = @_; my $x = ${$rv4}[$QX]; my $y = ${$rv4}[$QY]; my $z = ${$rv4}[$QZ]; my $w = ${$rv4}[$QW]; print "x $x, y $y, z $z, w $w\n"; } # print out a vector3 sub show_vec3($) { my ($rv3) = @_; my $x = ${$rv3}[0]; my $y = ${$rv3}[1]; my $z = ${$rv3}[2]; print "x $x, y $y, z $z\n"; } #/// The conjugate of the quaternion, this is also the #/// inverse for normalized quaternions #SGQuat conj(const SGQuat& v) #{ return SGQuat(-v(0), -v(1), -v(2), v(3)); } sub quat_conj($) { my ($rq) = @_; my @q = (0,0,0,0); $q[$QX] = -${$rq}[$QX]; $q[$QY] = -${$rq}[$QY]; $q[$QZ] = -${$rq}[$QZ]; $q[$QW] = ${$rq}[$QW]; # return [ -${$rq}[0], -${$rq}[1], -${$rq}[2], ${$rq}[3] ]; return \@q; } #/// Quaternion multiplication sub mult_quats($$) { my ($rv1,$rv2) = @_; my @v = (0,0,0,0); $v[$QX] = ${$rv1}[$QW] * ${$rv2}[$QX] + ${$rv1}[$QX] * ${$rv2}[$QW] + ${$rv1}[$QY] * ${$rv2}[$QZ] - ${$rv1}[$QZ] * ${$rv2}[$QY]; $v[$QY] = ${$rv1}[$QW] * ${$rv2}[$QY] - ${$rv1}[$QX] * ${$rv2}[$QZ] + ${$rv1}[$QY] * ${$rv2}[$QW] + ${$rv1}[$QZ] * ${$rv2}[$QX]; $v[$QZ] = ${$rv1}[$QW] * ${$rv2}[$QZ] + ${$rv1}[$QX] * ${$rv2}[$QY] - ${$rv1}[$QY] * ${$rv2}[$QX] + ${$rv1}[$QZ] * ${$rv2}[$QW]; $v[$QW] = ${$rv1}[$QW] * ${$rv2}[$QW] - ${$rv1}[$QX] * ${$rv2}[$QX] - ${$rv1}[$QY] * ${$rv2}[$QY] - ${$rv1}[$QZ] * ${$rv2}[$QZ]; return \@v; } #SGVec3 mult(const SGVec3& v1, const SGVec3& v2) #{ return SGVec3(v1(0)*v2(0), v1(1)*v2(1), v1(2)*v2(2)); } sub mult_vec3($$) { my ($rv1,$rv2) = @_; my @v = (0,0,0); $v[0] = ${$rv1}[0] * ${$rv2}[0]; $v[1] = ${$rv1}[1] * ${$rv2}[1]; $v[2] = ${$rv1}[2] * ${$rv2}[2]; return \@v; } #/// Scalar multiplication #template # SGVec3 operator*(S s, const SGVec3& v) #{ return SGVec3(s*v(0), s*v(1), s*v(2)); } sub scalar_mult_vector($$) { my ($s,$rv) = @_; my @v = (0,0,0); $v[0] = ${$rv}[0] * $s; $v[1] = ${$rv}[1] * $s; $v[2] = ${$rv}[2] * $s; return \@v; } # /// write the euler angles into the references # void getEulerRad(T& zRad, T& yRad, T& xRad) const { # T sqrQW = w()*w(); # T sqrQX = x()*x(); # T sqrQY = y()*y(); # T sqrQZ = z()*z(); # T num = 2*(y()*z() + w()*x()); # T den = sqrQW - sqrQX - sqrQY + sqrQZ; # if (fabs(den) <= SGLimits::min() && # fabs(num) <= SGLimits::min()) # xRad = 0; # else # xRad = atan2(num, den); # T tmp = 2*(x()*z() - w()*y()); # if (tmp <= -1) # yRad = T(0.5)*SGMisc::pi(); # else if (1 <= tmp) # yRad = -T(0.5)*SGMisc::pi(); # else # yRad = -asin(tmp); # num = 2*(x()*y() + w()*z()); # den = sqrQW + sqrQX - sqrQY - sqrQZ; # if (fabs(den) <= SGLimits::min() && # fabs(num) <= SGLimits::min()) # zRad = 0; # else { # T psi = atan2(num, den); # if (psi < 0) # psi += 2*SGMisc::pi(); # zRad = psi; # } # } sub getEulerRad($$$$) { my ($rq, $rzRad, $ryRad, $rxRad) = @_; my ($xRad,$yRad,$zRad); my $sqrQW = ${$rq}[$QW] * ${$rq}[$QW]; my $sqrQX = ${$rq}[$QX] * ${$rq}[$QX]; my $sqrQY = ${$rq}[$QY] * ${$rq}[$QY]; my $sqrQZ = ${$rq}[$QZ] * ${$rq}[$QZ]; # y * z + w * x my $num = 2 * ( ${$rq}[$QY] * ${$rq}[$QZ] + ${$rq}[$QW] * ${$rq}[$QX] ); my $den = $sqrQW - $sqrQX - $sqrQY + $sqrQZ; if ((abs($den) <= 0.0000001) && (abs($num) <= 0.0000001) ) { $xRad = 0; } else { $xRad = atan2($num, $den); } # x * z - w * y my $tmp = 2 * ( ${$rq}[$QX] * ${$rq}[$QZ] - ${$rq}[$QW] * ${$rq}[$QY] ); if ($tmp <= -1) { $yRad = 0.5 * $SGD_PI; } elsif (1 <= $tmp) { $yRad = - 0.5 * $SGD_PI; } else { $yRad = -asin($tmp); # needs Math::Trig } # x * y + w * z $num = 2 * ( ${$rq}[$QX] * ${$rq}[$QY] + ${$rq}[$QW] * ${$rq}[$QZ] ); $den = $sqrQW + $sqrQX - $sqrQY - $sqrQZ; if ((abs($den) <= 0.0000001) && (abs($num) <= 0.0000001) ) { $zRad = 0; } else { my $psi = atan2($num, $den); if ($psi < 0) { $psi += 2 * $SGD_PI; } $zRad = $psi; } # pass value back ${$rxRad} = $xRad; ${$ryRad} = $yRad; ${$rzRad} = $zRad; } # uses getEulerRad, and converts to degrees sub getEulerDeg($$$$) { my ($rq,$rzDeg,$ryDeg,$rxDeg) = @_; my ($xRad,$yRad,$zRad); getEulerRad($rq, \$zRad, \$yRad, \$xRad); # pass converted values back ${$rzDeg} = fgs_rad2deg($zRad); ${$ryDeg} = fgs_rad2deg($yRad); ${$rxDeg} = fgs_rad2deg($xRad); } # static SGQuat fromRealImag(T r, const SGVec3& i) { # SGQuat q; # q.w() = r; # q.x() = i.x(); # q.y() = i.y(); # q.z() = i.z(); # return q; } sub fromRealImag($$) { my ($r, $ri) = @_; my @q = (0,0,0,0); $q[$QW] = $r; $q[$QX] = ${$ri}[0]; $q[$QY] = ${$ri}[1]; $q[$QZ] = ${$ri}[2]; return \@q; } # /// Create a quaternion from the angle axis representation where the angle # /// is stored in the axis' length # static SGQuat fromAngleAxis(const SGVec3& axis) { # T nAxis = norm(axis); # if (nAxis <= SGLimits::min()) # return SGQuat::unit(); # T angle2 = T(0.5)*nAxis; # return fromRealImag(cos(angle2), T(sin(angle2)/nAxis)*axis); } sub fromAngleAxis($) { my ($raxis) = @_; my $nAxis = norm_vector_length($raxis); if ($nAxis <= 0.0000001) { my @arr = (0,0,0,0); return \@arr; # SGQuat::unit(); } my $angle2 = $nAxis * 0.5; my $sang = sin($angle2) / $nAxis ; my $cang = cos($angle2); #print "nAxis = $nAxis, ange2 = $angle2, saxa = $sang\n"; my $rv = scalar_mult_vector($sang,$raxis); #print "san "; #show_vec3($rv); #return fromRealImag(cos(angle2), T(sin(angle2)/nAxis)*axis); return fromRealImag( $cang, $rv ); } # /// Return a quaternion rotation from the earth centered to the # /// simulation usual horizontal local frame from given # /// longitude and latitude. # /// The horizontal local frame used in simulations is the frame with x-axis # /// pointing north, the y-axis pointing eastwards and the z axis # /// pointing downwards. # static SGQuat fromLonLatRad(T lon, T lat) # SGQuat q; # T zd2 = T(0.5)*lon; # T yd2 = T(-0.25)*SGMisc::pi() - T(0.5)*lat; # T Szd2 = sin(zd2); # T Syd2 = sin(yd2); # T Czd2 = cos(zd2); # T Cyd2 = cos(yd2); # q.w() = Czd2*Cyd2; # q.x() = -Szd2*Syd2; # q.y() = Czd2*Syd2; # q.z() = Szd2*Cyd2; # return q; } sub fromLonLatRad($$) { my ($lonr,$latr) = @_; my @q = (0,0,0,0); my $zd2 = 0.5 * $lonr; my $yd2 = -0.25 * $SGD_PI - (0.5 * $latr); my $Szd2 = sin($zd2); my $Syd2 = sin($yd2); my $Czd2 = cos($zd2); my $Cyd2 = cos($yd2); $q[$QW] = $Czd2 * $Cyd2; $q[$QX] = - $Szd2 * $Syd2; $q[$QY] = $Czd2 * $Syd2; $q[$QZ] = $Szd2 * $Cyd2; return \@q; } #void euler_get(float lat, float lon, float ox, float oy, float oz, # float *head, float *pitch, float *roll) #{ # /* FGMultiplayMgr::ProcessPosMsg */ # SGVec3f angleAxis; # angleAxis(0) = ox; # angleAxis(1) = oy; # angleAxis(2) = oz; # SGQuatf ecOrient; # ecOrient = SGQuatf::fromAngleAxis(angleAxis); # /* FGAIMultiplayer::update */ # float lat_rad, lon_rad; # lat_rad = lat * SGD_DEGREES_TO_RADIANS; # lon_rad = lon * SGD_DEGREES_TO_RADIANS; # SGQuatf qEc2Hl = SGQuatf::fromLonLatRad(lon_rad, lat_rad); # SGQuatf hlOr = conj(qEc2Hl) * ecOrient; # float hDeg, pDeg, rDeg; # hlOr.getEulerDeg(hDeg, pDeg, rDeg); # if(head) # *head = hDeg; # if(pitch) # *pitch = pDeg; # if(roll) # *roll = rDeg; #} sub euler_get($$$$$$$$) { my ($lat, $lon, $ox, $oy, $oz, $rhead, $rpitch, $rroll) = @_; #/* FGMultiplayMgr::ProcessPosMsg */ my @angleAxis = ($ox,$oy,$oz); #push(@angleAxis, $ox); #push(@angleAxis, $oy); #push(@angleAxis, $oz); #print "angleAxis "; #show_vec3(\@angleAxis); my $recOrient = fromAngleAxis(\@angleAxis); # ecOrient = SGQuatf::fromAngleAxis(angleAxis); #print "ecOrient "; #show_quat($recOrient); #/* FGAIMultiplayer::update */ my ($lat_rad, $lon_rad); $lat_rad = $lat * $SGD_DEGREES_TO_RADIANS; $lon_rad = $lon * $SGD_DEGREES_TO_RADIANS; my $qEc2Hl = fromLonLatRad($lon_rad, $lat_rad); #print "fromLonLatRad "; #show_quat($qEc2Hl); my $con = quat_conj($qEc2Hl); #print "conj "; #show_quat($con); my $rhlOr = mult_quats($con, $recOrient); #print "mult "; #show_quat($rhlOr); getEulerDeg($rhlOr, $rhead, $rpitch, $rroll ); } # ================================================================ # # End SimGear Fuctions # ================================================================ # # XML output, for FGMap my($XML_HEADER) = <$log_file") { print "ERROR: Log file FAILED\n"; exit 1; } } sub do_xml_header { my($cnt) = @_; return ${XML_HEADER}."\n\n"; } sub do_xml_single { my($callsign, $server_ip, $model, $lat, $lon, $alt, $head, $pitch, $roll) = @_; return < XML } sub do_xml_tail { return "\n\n"; } my(%xml_output) = ( 'header' => \&do_xml_header, 'single' => \&do_xml_single, 'tail' => \&do_xml_tail, ); ###### my($KML_HEADER) = < FlightGear MP server map 1 KML return ${KML_HEADER}.${kml}; } sub do_kml_single { my($callsign, $server_ip, $model, $lat, $lon, $alt, $head, $pitch, $roll) = @_; push(@this_callsigns, $callsign); # simple feet to meter $alt *= 0.3048; my($model_url) = &kml_model_url_get($model); return < ${callsign} ${callsign}: ${model} absolute ${lat} ${lon} ${alt} ${head} ${pitch} ${roll} ${DAE_SCALE} ${DAE_SCALE} ${DAE_SCALE} ${model_url} onChange KML } sub do_kml_tail { my($callsigns_str) = join(';', @this_callsigns); return < Update http://${HTTP_HOST}/${DOCUMENT_PATH}/fg_server_kml.cgi?${act_server}:${port}&callsigns=${callsigns_str} onInterval ${KML_REFRESH_INTERVAL} KML } my(%kml_normal_output) = ( 'header' => \&do_kml_header, 'single' => \&do_kml_single, 'tail' => \&do_kml_tail, ); # KML (update) output, for Google Earth sub do_kml_update_header { my($kml) = < http://${HTTP_HOST}/${DOCUMENT_PATH}/fg_server_kml.cgi?${act_server}:${port} KML return ${KML_HEADER}.${kml}; } sub do_kml_update_single { my($callsign, $server_ip, $model, $lat, $lon, $alt, $head, $pitch, $roll) = @_; # simple feet to meter $alt *= 0.3048; my($model_url) = &kml_model_url_get($model); push(@this_callsigns, $callsign); if(grep(/^${callsign}$/, @last_callsigns)) { # We have it before, it return < ${lat} ${lon} ${alt} ${head} ${pitch} ${roll} KML } else { # New one, it return < ${callsign} ${callsign}: ${model} absolute ${lat} ${lon} ${alt} ${head} ${pitch} ${roll} ${DAE_SCALE} ${DAE_SCALE} ${DAE_SCALE} ${model_url} onChange KML } } sub do_kml_update_tail { my($callsign); my($kml); my($callsigns_str) = join(';', @this_callsigns); foreach $callsign (@last_callsigns) { if(!grep(/^${callsign}$/, @this_callsigns)) { $kml .= < KML } } $kml .= < http://${HTTP_HOST}/${DOCUMENT_PATH}/fg_server_kml.cgi?${act_server}:${port}&callsigns=${callsigns_str} KML } my(%kml_update_output) = ( 'header' => \&do_kml_update_header, 'single' => \&do_kml_update_single, 'tail' => \&do_kml_update_tail, ); sub escape_strs { my($str) = @_; $str =~ s/"/\"/g; $str =~ s/'/\'/g; $str =~ s/\&/\&/g; $str =~ s/>/\>/g; $str =~ s/= 65536) { exit(-1); } } prt("Host $HTTP_HOST, query $QUERY_STRING, script $SCRIPT_NAME, server $act_server, port $port, callsign $in_callsigns\n"); if($0 =~ m/fg_server_kml.cgi$/) { if($in_callsigns =~ m/^callsigns=(.*)$/) { $in_callsigns = $1; @last_callsigns = split(/;/, $in_callsigns); %ocs = %kml_update_output; } else { %ocs = %kml_normal_output; } } else { %ocs = %xml_output; } sub do_socket { my($ret) = ""; my($pilot_total) = 0; my($pilot_cnt) = 0; my($head, $pitch, $roll); prt("Opening socket to $act_server:$port...\n"); my($socket) = IO::Socket::INET->new(PeerAddr => $act_server, PeerPort => $port, Proto => "tcp", Type => SOCK_STREAM, Timeout => 10); if($socket) { while($l = <$socket>) { chomp($l); if ($write_log) { print $LF "# ".get_YYYYMMDD_hhmmss_UTC(time())."\n"; print $LF "$l\n"; } if((substr($l, 0, 1) eq "#") && ($l =~ /^# (\d+) .*? online/)) { $pilot_total = $1; $ret .= $ocs{'header'}->($pilot_total); } #elsif($l =~ m/^(.*)@(.*?): (-?[0-9]+\.[0-9]+) (-?[0-9]+\.[0-9]+) (-?[0-9]+\.[0-9]+) (-?[0-9]+\.[0-9]+) (-?[0-9]+\.[0-9]+) (-?[0-9]+\.[0-9]+) (-?[0-9]+\.[0-9]+) (-?[0-9]+\.[0-9]+) (-?[0-9]+\.[0-9]+) (.*?)$/) elsif($l =~ m/^(.*)@(.*?): (-?[0-9\.]+) (-?[0-9\.]+) (-?[0-9\.]+) (-?[0-9\.]+) (-?[0-9\.]+) (-?[0-9\.]+) (-?[0-9\.]+) (-?[0-9\.]+) (-?[0-9\.]+) (.*?)$/) { my($callsign, $server_ip, $x, $y, $z, $lat, $lon, $alt, $ox, $oy, $oz, $model) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12); $callsign = &escape_strs(${callsign}); $callsign =~ s/^# //g; if($callsign and $model) { #$model =~ s#.*/(.*?)\..*?$#$1#; $model =~ s#.*/(.*?)#$1#; $model =~ s/\..*?$//; if ($add_sg_math) { ($head, $pitch, $roll) = &sgmath::euler_get($lat, $lon, $ox, $oy, $oz); } else { $head = 0; $pitch = 0; $roll = 0; euler_get($lat, $lon, $ox, $oy, $oz, \$head, \$pitch, \$roll); } $ret .= $ocs{'single'}->($callsign, $server_ip, $model, $lat, $lon, $alt, $head, $pitch, $roll); $pilot_cnt++; if($pilot_cnt >= $pilot_total) { prt("Done pilot count $pilot_cnt...\n"); close($socket); undef($socket); last; } } } } $ret .= $ocs{'tail'}->(); if($socket) { close($socket); } } else { prt("Socket to $act_server:$port FAILED\n"); $ret .= $ocs{'header'}->(0); $ret .= $ocs{'tail'}->(); } return $ret; } # sample data 2010-12-23 13:00 UTC sub sample_serv_data() { my $sd = <($pilot_total); } #elsif($l =~ m/^(.*)@(.*?): (-?[0-9]+\.[0-9]+) (-?[0-9]+\.[0-9]+) (-?[0-9]+\.[0-9]+) (-?[0-9]+\.[0-9]+) (-?[0-9]+\.[0-9]+) (-?[0-9]+\.[0-9]+) (-?[0-9]+\.[0-9]+) (-?[0-9]+\.[0-9]+) (-?[0-9]+\.[0-9]+) (.*?)$/) elsif($l =~ m/^(.*)@(.*?): (-?[0-9\.]+) (-?[0-9\.]+) (-?[0-9\.]+) (-?[0-9\.]+) (-?[0-9\.]+) (-?[0-9\.]+) (-?[0-9\.]+) (-?[0-9\.]+) (-?[0-9\.]+) (.*?)$/) { my($callsign, $server_ip, $x, $y, $z, $lat, $lon, $alt, $ox, $oy, $oz, $model) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12); $callsign = &escape_strs(${callsign}); $callsign =~ s/^# //g; if($callsign and $model) { #$model =~ s#.*/(.*?)\..*?$#$1#; $model =~ s#.*/(.*?)#$1#; $model =~ s/\..*?$//; if ($add_sg_math) { ($head, $pitch, $roll) = &sgmath::euler_get($lat, $lon, $ox, $oy, $oz); } else { $head = 0; $pitch = 0; $roll = 0; euler_get($lat, $lon, $ox, $oy, $oz, \$head, \$pitch, \$roll); push(@conversions, [$lat, $lon, $ox, $oy, $oz, $head, $pitch, $roll] ); } $ret .= $ocs{'single'}->($callsign, $server_ip, $model, $lat, $lon, $alt, $head, $pitch, $roll); $pilot_cnt++; if($pilot_cnt >= $pilot_total) { close($socket); undef($socket); last; } } } } $ret .= $ocs{'tail'}->(); #if($socket) #{ # close($socket); #} } else { $ret .= $ocs{'header'}->(0); $ret .= $ocs{'tail'}->(); } return $ret; } sub get_socket_lines() { my $dat = sample_serv_data(); my @arr = split(/\n/,$dat); return \@arr; } sub do_testing() { my $ra = get_socket_lines(); my $ret = process_lines($ra); if ($output_structure_value) { # output the conversion as an structure array # 0 1 2 3 4 5 6 7 # push(@conversions, [$lat, $lon, $ox, $oy, $oz, $head, $pitch, $roll] ); my $ra = \@conversions; my $cnt = scalar @{$ra}; prt("Got $cnt conversions...\n"); my ($lat, $lon, $ox, $oy, $oz, $head, $pitch, $roll); my ($i,$i2); for ($i = 0; $i < $cnt; $i++) { $i2 = $i + 1; $lat = ${$ra}[$i][0]; $lon = ${$ra}[$i][1]; $ox = ${$ra}[$i][2]; $oy = ${$ra}[$i][3]; $oz = ${$ra}[$i][4]; $head = ${$ra}[$i][5]; $pitch = ${$ra}[$i][6]; $roll = ${$ra}[$i][7]; prt(" { $lat, $lon, $ox, $oy, $oz, $head, $pitch, $roll }, // $i2\n" ); } } return $ret; } sub do_testing2 { my($ret) = ""; my($default_lat) = 37.613545; my($default_lon) = -122.357237; my(@test_pilots) = ( { callsign => 'pilot1', model => 'model1', server_ip => '127.0.0.1', lat => $default_lat, lon => $default_lon, alt => 0, head => 0, pitch => 0, roll => 0, }, { callsign => 'pilot2', model => 'model2', server_ip => '127.0.0.1', lat => $default_lat + 0.01, lon => $default_lon + 0.01, alt => 0, head => 90, pitch => 0, roll => 0, }, { callsign => 'pilot3', model => 'model3', server_ip => '127.0.0.1', lat => $default_lat + 0.02, lon => $default_lon + 0.02, alt => 0, head => 45, pitch => 0, roll => 0, }, { callsign => 'pilot4', model => 'model4', server_ip => '127.0.0.1', lat => $default_lat + 0.03, lon => $default_lon + 0.03, alt => 0, head => 180, pitch => 0, roll => 0, }, { callsign => 'pilot5', model => 'model5', server_ip => '127.0.0.1', lat => $default_lat + 0.04, lon => $default_lon + 0.04, alt => 0, head => 270, pitch => 0, roll => 0, }, ); my($pilot_total) = $#test_pilots; $ret .= $ocs{'header'}->($pilot_total); foreach my $p (@test_pilots) { $ret .= $ocs{'single'}->($p->{'callsign'}, $p->{'server_ip'}, $p->{'model'}, $p->{'lat'}, $p->{'lon'}, $p->{'alt'}, $p->{'head'}, $p->{'pitch'}, $p->{'roll'}); } $ret .= $ocs{'tail'}->(); return $ret; } # test_conv(); sub do_all_servers() { my ($i,$i2,$serv,$res); $res = ''; for ($i = 1; $i < 15; $i++) { if ($i < 10) { $i2 = "0".$i; } else { $i2 = $i; } $serv = $serv = "mpserver${i2}.flightgear.org"; $act_server = $serv; $res = "\nDoing server $act_server\n"; $res .= do_socket(); $res .= "\n"; if ($write_log) { print $LF $res; } } return "\n"; } if ($testing) { if ($test_socket) { if ($do_def_serv) { $act_server = $def_server; $port = 5001; prt("Testing fgms 14 $act_server $port...\n"); $output = do_socket(); } elsif ($do_win7) { $act_server = "192.168.1.21"; $port = 5001; prt("Testing Win7-PC $act_server $port...\n"); $output = do_socket(); } elsif ($do_all) { prt("Testing all do_all_servers()...\n"); $output = do_all_servers(); } elsif ($do_fgx) { #$act_server = "fgx.ch"; $act_server = "217.150.241.100"; #$port = 5011; $port = 5001; prt("Testing fgx $act_server $port...\n"); $output = do_socket(); } elsif ($do_dell01) { $act_server = "192.168.1.174"; $port = 5001; prt("Testing Dell01 $act_server $port...\n"); $output = do_socket(); } elsif ($do_dell02) { $act_server = "192.168.1.105"; $port = 5001; prt("Testing Dell02 $act_server $port...\n"); $output = do_socket(); } else { prt("Testing: Doing do_socket()...\n"); $output = &do_socket(); } } else { prt("Testing: Doing do_testing()...\n"); $output = &do_testing(); } } else { prt("Doing do_socket()...\n"); $output = &do_socket(); } binmode(STDOUT, ":utf8"); print($output); if ($write_log) { print $LF $output; print "Written to $log_file...\n"; } print "SGD_MIN = $SGD_MIN\n"; #if ($testing) { # my $file = "tempxml.xml"; # if (open OUT, ">$file") { # printf OUT $output; # close OUT; # } #} if ($write_log) { close $LF; } exit(0); sub test_conv() { my $lat = 53.348596; my $lon = -2.276554; my $alt = 241.742828; my $ox = -2.904634; my $oy = 1.457308; my $oz = 0.992861; my ($head, $roll, $pitch); euler_get($lat, $lon, $ox, $oy, $oz, \$head, \$pitch, \$roll); print "Head $head, pitch $pitch, roll $roll\n"; exit 1; } sub some_results { my $msg = <