1=head1 NAME 2 3Astro::App::Satpass2::TUTORIAL - Tutorial on the use of Astro::App::Satpass2 4 5=head1 INTRODUCTION 6 7This package was created to provide a flexible way to predict satellite 8positions, passes, and visibility. Unfortunately, with flexibility comes 9complexity, more often than not. This document's purpose is to get you 10up and running, and walk you through some of the things the package can 11do. 12 13The simplest way to access C<Astro::App::Satpass2> functionality is 14through the F<satpass2> script, and that what this tutorial does. 15 16To get any real use out of this package, you need satellite orbital 17data. The best source is L<https://www.space-track.org/>, but this 18requires registration, so this tutorial will assume you are not 19registered and use data from other sources. Most other sources are 20redistributions of Space Track data, and will not be as up-to-date, but 21are generally good enough for non-critical computations. 22 23=head1 SETUP 24 25The first thing that needs to be done, of course, is to install 26C<Astro::App::Satpass2> itself. The recommended way to do this is 27normally to use one of the F<CPAN> tools. With F<cpan>, the installation 28would be simply 29 30 $ cpan 31 ... front matter ... 32 cpan> install Astro::App::Satpass2 33 ... cpan downloads, tests, and installs this package 34 and all dependencies ... 35 cpan> exit 36 37You could equally well use CPANPLUS (F<cpanp>) or cpanminus (F<cpanm>); 38the choice is yours. If you are using Active State's F<ActivePerl>, you 39should use their F<ppi> tool to install distribution 40F<Astro-App-Satpass2>. 41 42There are several Perl modules that this package considers optional, but 43which will be used if they are available. Unless stated otherwise, the 44examples in this tutorial assume that optional module 45L<Astro::SpaceTrack|Astro::SpaceTrack> is installed, so that you can 46download satellite orbital data directly into C<Astro::App::Satpass2>. 47 48The author also recommends optional module L<Date::Manip|Date::Manip>, 49but since the latest version of this module only installs under Perl 505.10 and above, this tutorial will not assume it is installed. When it 51is not, C<Astro::App::Satpass2> uses a home-grown ISO-8601-ish date 52parser. All dates specified in the examples will be compatible with both 53date parsers. 54 55It does not matter whether you install optional modules before or after 56installing C<Astro::App::Satpass2>; it will use them if it finds them. 57 58=head1 CONFIGURATION 59 60There are several possibilities for configuring C<Astro::App::Satpass2>. 61This tutorial will cover the following: 62 63=head2 Configuring from a F<satpass> initialization file 64 65If you already have configured the initialization file for the 66F<satpass> script packaged in the C<Astro-satpass> distribution, 67C<Astro::App::Satpass2> will read this script, making allowances for at 68least some of the incompatibilities between the two tools. 69 70Since the intent is to remove the F<satpass> compatibility when 71F<satpass> is retired, you may at some time wish to convert your 72F<satpass> initialization file to a C<Astro::App::Satpass2> 73initialization file. To do this from inside the F<satpass2> script, 74simply issue the command 75 76 satpass2> save -changes 77 78The name and location of the saved file depend on your operating system, 79but will be reported when you issue this command. Once the file is 80saved, you can display its location using 81 82 satpass2> initfile 83 84The configuration file's location is actually determined using 85C<< File::HomeDir->my_dist_config( 'Astro-App-Satpass2' ) >>. See the 86L<File::HomeDir|File::HomeDir> documentation for details. 87 88Subsequent runs of the F<satpass2> script will initialize from the new 89file. This form of the C<save> command just saves changes from the 90default configuration. If you wish to save all configuration, omit the 91C<-changes> option. 92 93Be aware that C<save> only saves the configuration of the 94C<Astro::App::Satpass2> object and its related helper objects. If your 95initialization file does other things, like download data and make 96predictions, these will not be written to the new file, and you must add 97them back by hand. 98 99=head2 Configuring manually 100 101Before you do any predictions, C<Astro::App::Satpass2> needs to know 102where you are. The embedded L<Astro::SpaceTrack|Astro::SpaceTrack> 103object will also need some configuration so it knows how to fetch data 104from its various sources. 105 106Specifically, you need your latitude, longitude (from Greenwich 107England), and height above sea level. The height is least critical, and 108any reasonable guess will probably work. 109 110Latitude and longitude can be specified in either decimal degrees (e.g. 11140.5) or degrees, minutes and seconds (e.g. 40d30m0s). B<South> latitude 112and B<West> longitude are negative. 113 114Height is assumed to be in meters, but you can be specify it in feet by 115appending 'ft'. For example, '10' specifies 10 meters, as does '10m', 116but '10ft' specifies 10 feet. 117 118Because it would be painful to specify your position every time you use 119it, C<Astro::App::Satpass2> allows a configuration file. The example 120that follows will end by creating a configuration file and storing the 121configuration in it. 122 123And here, finally, is the example. We make the egregious assumption that 124the President of the United States uses this software, so we use the 125executive mansion as our location. 126 127 $ satpass2 128 ... front matter displayed ... 129 satpass2> 130 satpass2> # This is a comment, as is any line beginning 131 satpass2> # with a hash mark ('#'). Comments and blank 132 satpass2> # lines are ignored. 133 satpass2> 134 satpass2> # Enter the name of our location. This is for 135 satpass2> # information only, and will be displayed by 136 satpass2> # the location command. Command arguments that 137 satpass2> # contain spaces need to be quoted. 138 satpass2> set location '1600 Pennsylvania Ave, Washington DC' 139 satpass2> 140 satpass2> # Set our latitude and longitude. 141 satpass2> set latitude 38d53m55.5s longitude -77d2m15.7s 142 satpass2> 143 satpass2> # Set our height above sea level. 144 satpass2> set height 54.72ft 145 satpass2> 146 satpass2> # Some of our data sources will try to fetch 147 satpass2> # their data from Space Track when we ask for 148 satpass2> # it. We are assuming no Space Track username, 149 satpass2> # so we tell them to just give us what they have. 150 satpass2> spacetrack set direct 1 151 satpass2> 152 satpass2> # Some data sources come either with or without the 153 satpass2> # actual name of the spacecraft. We want the name 154 satpass2> # if it is available. 155 satpass2> spacetrack set with_name 1 156 satpass2> 157 satpass2> # Save our configuration. All we really need to 158 satpass2> # save are the changes from the default. 159 satpass2> save -changes 160 satpass2> 161 satpass2> # We can now exit. When we restart, we will get 162 satpass2> # the configuration we just set up. 163 satpass2> exit 164 165=head2 Geocoding the address 166 167Looking up a latitude and longitude can be a bit of a pain. If you live 168in the United States, C<Astro::App::Satpass2> can geocode your address, 169and then query the U. S. Geological Survey for your height above sea 170level. 171 172This requires two more optional modules: 173L<Geo::Coder::OSM|Geo::Coder::OSM> and 174L<Geo::WebService::Elevation::USGS|Geo::WebService::Elevation::USGS>. 175With these installed, the address entry in the previous example becomes 176 177 satpass2> geocode '1600 Pennsylvania Ave NW, Washington DC USA' 178 179When you issue this command, the geocoded location is displayed, 180formatted as C<set> commands: 181 182 set location '1600 Pennsylvania Avenue Northwest, 183 Washington, District of Columbia USA' 184 set latitude 38.8976989 185 set longitude -77.036553192281 186 set height 18.81 187 188If more than one result is returned, all are displayed but no location 189is set. If no result is returned, an exception is raised. 190 191=head1 PREDICTING PASSES 192 193The main use of this package is probably predicting when satellites are 194going to pass over the observer. 195 196=head2 Visible Passes 197 198This is the functionality that tells you when you can go out and see a 199satellite, assuming clear skies and a satellite large enough to be 200visible. Visible passes require three things to happen: 201 202* The satellite must be above the horizon (of course!), 203 204* The Sun must be shining on the satellite (they do not have lights), 205and 206 207* The Sun must not be shining where you are (otherwise the sky is too 208bright to see the satellite). 209 210The example is for the International Space Station, and we will 211use NASA's predictions of its orbit over the next week as a starting 212point. 213 214 $ satpass 215 ... front matter ... 216 satpass2> 217 satpass2> # Tell the Astro::SpaceTrack object to fetch us 218 satpass2> # all the predicted orbital elements from NASA's 219 satpass2> # Human Space Flight web site. We include the 220 satpass2> # effective date, since the data may include 221 satpass2> # planned changes in orbit. 222 satpass2> spacetrack spaceflight -all -effective 223 satpass2> 224 satpass2> # Make the default pass prediction, which is for 225 satpass2> # seven days starting today at noon. 226 satpass2> pass 227 228You may want to print this information and stick it on your 229refrigerator. C<Astro::App::Satpass2> has something a bit like Unix 230output redirection to get your information into a file: 231 232 satpass2> pass >pass.txt 233 234After which you open F<pass.txt> in some simple editor and print it. A 235word-processing editor will probably not work satisfactorily unless you 236set the entire document to a mono-space font. 237 238You may want a prediction for some specific date. The following example 239does a prediction for the night of April 1 2011 (specifically, for one 240day starting at noon on that day) and saves the output in 241F<april_fool.txt>. 242 243 satpass2> pass '2011/4/1 12:00:00' +1 >april_fool.txt 244 245Note that the date is quoted because of the space between the date and 246the time. If you had L<Date::Manip|Date::Manip> installed, you could 247specify the date more flexibly, as (say) C<'1-Apr-2011 noon'>. 248 249=head2 Different Viewing Conditions 250 251C<Astro::App::Satpass2> assumes a few things about viewing conditions 252where you are. These may or may not be true. If they are not, you can 253change them. 254 255The settings discussed below are part of your configuration, and can be 256saved using 257 258 satpass2> save -changes 259 260as discussed above. If you have already saved your configuration you 261will be asked whether you want to overwrite the old configuration. Any 262answer beginning with 'y' (case-insensitive) will be considered true. 263Any other answer will be considered false. 264 265=head3 The horizon 266 267C<Astro::App::Satpass2> assumes that you do not have a very good 268horizon, and that you can not see a satellite until it is at least 20 269degrees above the horizon, and therefore does not report passes that do 270not get at least 20 degrees above the horizon. If you are at the beach 271you may be able to see to within 5 degrees of the horizon. You can 272configure C<Astro::App::Satpass2> to report passes more than 5 degrees 273above the horizon by 274 275 satpass2> set horizon 5 276 277If you are on the top of a mountain, you may even be able to see a bit 278over the normal horizon. If you can see 2 degrees over the horizon, 279 280 satpass2> set horizon -2 281 282=head3 Twilight 283 284C<Astro::App::Satpass2> does not predict visible passes that occur 285during the day, and it defines day as any time after the start of 286morning twilight and before the end of evening twilight. These in turn 287are defined as the point when the upper limb of the Sun passes above or 288below a given distance below the horizon. 289 290By default, C<Astro::App::Satpass2> uses civil twilight to decide 291whether it is day or night. This is defined as the point at which the 292upper limb of the Sun is 6 degrees below the horizon. For a dimmer 293satellite, you may want to use nautical twilight (9 degrees below the 294horizon) or astronomical twilight (12 degrees below the horizon). You 295can change to nautical twilight using 296 297 satpass2> set twilight nautical 298 299and similarly for astronomical. Or, you can define your own twilight by 300entering it in degrees, remembering that degrees below the horizon are 301negative. If you are looking for the International Space Station, you 302may be able to spot it with the Sun only 3 degrees below the horizon: 303 304 satpass2> set twilight -3 305 306=head2 All Passes 307 308If you are interested in communicating with the satellite rather than 309looking at it, all you care about is whether the satellite is above the 310horizon, not whether it is day or night or whether the satellite is 311illuminated by the Sun. In this case you want to 312 313 satpass2> set visible 0 314 315which turns off the latter two checks and reports any pass of the 316satellite over your location, visible or not. To go back to predicting 317just visible passes, 318 319 satpass2> set visible 1 320 321=head1 IRIDIUM FLARES 322 323I know of no scientific value to these, but they are fun to watch. The 324Iridium constellation is 66 satellites (plus spares) used for satellite 325telephone service. The original-design Iridium satellites are triangular 326prisms, with one main mission antenna leaning out from each face of the 327prism. The main mission antennae are about the size of a door, flat, and 328shiny, and because the satellites are maintained in a precise 329orientation in orbit, it can be predicted when one of these antennae 330will reflect the Sun to a given position. A bright flare can be brighter 331than Venus at its brightest, and under good conditions is visible during 332the day. 333 334=head2 Predicting Flares 335 336Predicting flares is a bit like predicting satellite passes - you 337download the orbital data and predict the flare from the data. 338 339 $ satpass2 340 ... front matter ... 341 satpass2> 342 satpass2> # Download the data on Iridium satellites. 343 satpass2> spacetrack celestrak iridium 344 satpass2> 345 satpass2> # Predict flares for the next seven days, 346 satpass2> # starting today at noon. 347 satpass2> flare 348 349This will take a while, because it has to cover all 66 in-service 350Iridium satellites, 24 hours per day. And this does not include spares, 351which are usually kept under control, just to prove that they work. If 352you want them as well, 353 354 satpass2> flare -spare 355 356If you want a copy of all this to stick on your refrigerator door, 357capture it to a file in the same way you captured the pass data: 358 359 satpass2> flare >flare.txt 360 361If you want to append it to the F<pass.txt> file created for satellite 362passes, 363 364 satpass2> flare >>pass.txt 365 366just as you would under Unix. 367 368But maybe you are not interested in daylight flares. If not, 369 370 satpass2> flare -noday 371 372If you are also not interested in flares at 4:00 AM, 373 374 satpass2> flare -noam -noday 375 376or equivalently, 377 378 satpass2> flare -pm 379 380The C<-am>, C<-day>, and C<-pm> options select which flares are 381reported, by time. The C<-am> option selects flares from midnight until 382the start of morning twilight; C<-day> selects flares from the start of 383morning twilight to the end of evening twilight, and C<-pm> selects 384flares from the end of evening twilight until midnight. 385 386The options can be negated by prefixing C<no> to the option name (e.g. 387C<-noday>). If you specify no options, they are all considered to be 388asserted. If you specify no asserted options, all unspecified options 389are considered to be asserted. Otherwise, only explicitly-asserted 390options are considered to be asserted. 391 392If you do not want flares for a particular part of the day, calculations 393for that part of the day are not done. This can speed the prediction 394process. 395 396=head2 Different Flare Visibility 397 398Flare brightness is measured in magnitude, a system used by astronomers 399to measure the brightness of stars. This system goes back a couple 400thousand years, and originally classified the brightest stars as first 401magnitude, the less-bright stars as second magnitude, and so on. The 402system has been formalized to a logarithmic scale in which a brightness 403difference of five magnitudes represents a light intensity difference of 404a factor of 100. Brighter stars may have negative magnitudes (Sirius is 405about -1.4). 406 407Obviously a flare that would be fairly bright at night might be 408completely invisible during the day, so day and night have separate 409settings to control the minimum reportable brightness. 410C<Astro::App::Satpass2> uses the C<flare_mag_day> setting to determine 411the dimmest reportable flare during the day; this defaults to C<-6>. The 412dimmest reportable flare at night is determined by the 413C<flare_mag_night> setting, which defaults to C<0>. 414 415In order to duplicate (fairly closely) the Iridium flares reported by 416L<https://www.heavens-above.com/>, you will want to tweak 417C<Astro::App::Satpass2>'s settings a bit: 418 419 satpass2> set twilight -1.8 flare_mag_night -1 420 421seems to come fairly close. 422 423=head1 OTHER CUSTOMIZATIONS 424 425There are other customizations of the output that you may want. 426 427=head2 Location 428 429If you want to display your location, just issue the 430 431 satpass2> location 432 433command. The output of this can be directed to a file, just as the 434output of any other command. For a nice list of passes and flares for 435your refrigerator door, you can do something like this: 436 437 satpass2> location >this_week.txt 438 satpass2> spacetrack spaceflight -all -effective 439 satpass2> pass >>this_week.txt 440 satpass2> spacetrack celestrak iridium 441 satpass2> flare -pm >>this_week.txt 442 satpass2> exit 443 444=head2 Date and Time Format 445 446By default, date and time are displayed in an ISO-8601-ish format. If 447you want something friendlier, you can specify a C<strftime (3)> format 448independently for the date and the time. These settings can be saved to 449your initialization file just like any other setting. 450 451The date and time format settings belong to the formatter object, which 452is a separate subsystem all to itself. So: 453 454 satpass2> 455 satpass2> # Display the date as weekday day-month-year 456 satpass2> formatter date_format '%a %d-%b-%Y' 457 satpass2> 458 satpass2> # Display the time as 1-12 AM or PM 459 satpass2> formatter time_format '%I:%M:%S %p' 460 satpass2> 461 satpass2> # Save the configuration, overwriting any previous one 462 satpass2> save -changes -overwrite 463 464=head2 The Julian Calendar 465 466No, there were no satellites in orbit when the last known holdout 467(Romania) adopted the Gregorian calendar. But the Sun and Moon have been 468rising and setting much longer than satellites have. 469 470If you install 471L<DateTime::Calendar::Christian|DateTime::Calendar::Christian> and 472properly configure C<satpass2>, you will be able to both parse and 473display dates in both the Gregorian and Julian calendars. 474 475=head3 Parsing Julian Calendar Dates 476 477The primary date parser is L<Date::Manip|Date::Manip>, which does not 478support Julian dates. But if you use the C<ISO8601> parser, you can 479configure it to parse a date as either Julian or Gregorian, depending on 480the date itself. 481 482What you have to do, in general, is use date parser 483L<Astro::App::Satpass2::ParseTime::ISO8601>, and set its 484L<back_end|Astro::App::Satpass2::Utils/back_end> attribute 485to C<'DateTime::Calendar::Christian'>. You must, of course have this 486module installed, and you can shorten the setting to just 487C<'Christian'>. You should see the documentation for full details, but 488with the C<satpass2> script the configuration would look something like 489this: 490 491 satpass2> # Configure the ISO8601 parser, with back end 492 satpass2> set time_parser ISO8601,back_end=Christian 493 494The L<DateTime::Calendar::Christian|DateTime::Calendar::Christian> 495module takes, as one of the arguments to C<new()>, a reform date, which 496defaults to the date it was first adopted in Italy, on October 15 1582 497(Gregorian). If you want something different you can append it to the 498value of C<back_end> and quote the whole value. The quotes must be 499either escaped or surrounded with outer quotes to protect them from the 500command parser. For example, to set the UK reform date, use 501 502 satpass2> set time_parser "ISO8601,back_end='Christian,reform_date=uk'" 503 504=head3 Formatting Julian Calendar Dates 505 506Here, you need to use the C<DateTime> date formatter, which will be the 507default if the L<DateTime|DateTime> module is installed. Since 508L<DateTime|DateTime> is a prerequisite for 509L<DateTime::Calendar::Christian|DateTime::Calendar::Christian>, 510installing this will make the proper date formatter the default. But 511before you can actually get Julian output dates, you need to configure 512the time formatter to use this class. Because the date formatter is 513managed by the formatter object, the C<satpass2> commands to configure 514it are 515 516 satpass2> # Configure the time formatter and reform date 517 satpass2> formatter time_formatter \ 518 > DateTime::Strftime,back_end=Christian 519 520A non-default reform date is specified the same way as for the parser, 521and the two reform dates need not be the same. 522 523The C<DateTime> C<strftime> formatter also supports, as a special case, 524format pattern C<'%{calendar_name}'>, which renders as either 525C<'Julian'> or C<'Gregorian'> as appropriate. Given 526 527 satpass2> formatter time_format \ 528 > '%{year_with_era}-%m-%d %{calendar_name}' 529 530The date of the assassination of Julius Caesar would be displayed as 531 532 '44BC-03-15 Julian' 533 534In point of fact, the way the C<%{calendar_name}> machinery works is 535that if the back end provides the C<is_julian()> method, you get 536C<'Julian'> if that method returns a true value, and C<'Gregorian'> if 537it does not. If the back end does not provide the C<is_julian()> method, 538whatever follows C<'DateTime::Calendar::'> in the back end's class name 539is used. If the back end does not begin with C<'DateTime::Calendar::'>, 540C<'Gregorian'> is used. 541 542Formatting Julian calendar dates in 543L<Astro::App::Satpass2::FormatTime::DateTime::Cldr|Astro::App::Satpass2::FormatTime::DateTime::Cldr> 544is unsupported, because 545L<DateTime::Calendar::Christian|DateTime::Calendar::Christian> lacks the 546C<format_cldr()> method. You may find that it works, because this module 547patches in C<format_cldr()> when it loads 548L<DateTime::Calendar::Christian|DateTime::Calendar::Christian> if it 549finds that that method does not already exist. But you may find that it 550does not work, because the patch messes with the internals of 551L<DateTime::Calendar::Christian|DateTime::Calendar::Christian>, and 552those might change without warning. I<Caveat coder.> 553 554=head1 INTERMEDIATE TOPICS 555 556This section covers things that are beyond just getting the application 557up and running. 558 559=head2 Time Zones 560 561By default, times are reported in your local zone. Summer time/daylight 562saving time is accounted for (unless the underlying Perl is broken), 563even when predictions cross the boundary between standard and summer 564time. But you may want some other zone. There are two cases here, 565depending on what optional modules you have installed. 566 567Without any optional modules, the only supported zone other than your 568default local zone is GMT. You can get GMT output by 569 570 satpass2> formatter gmt 1 571 572The default ISO-8601-ish time parser does not have a corresponding 573setting, but does allow you to append a C<'Z'> to the time to specify 574GMT. 575 576The default formatter object also has a C<tz> setting, but this is 577unsupported because it relies on the C<TZ> environment variable, and the 578author has no control over whether your OS' POSIX code supports this. 579You can try it with something like 580 581 satpass2> formatter tz MST7MDT 582 583(for Mountain time). If it works, fine. If not, you can make it work by 584installing L<DateTime|DateTime> and 585L<DateTime::TimeZone|DateTime::TimeZone>. Doing this also gives you the 586Olson database zone names (e.g. C<America/New_York>) if you prefer 587these. 588 589Similarly, if you install the optional L<Date::Manip|Date::Manip> 590module, you can set a default input zone other than your own by 591something like 592 593 satpass2> time_parser tz MST7MDT 594 595The C<time_parser> and C<formatter> time zones are set separately not 596only so that you can make them different, but because the author can not 597guarantee that the underlying modules will accept the same settings. 598 599=head2 Command Macros 600 601A command macro is simply a named set of C<Astro::App::Satpass2> 602commands, somewhat like a C<bash> shell function. A command macro is 603executed by giving its name, so in essence command macros are ways of 604creating new commands. 605 606The definition of a macro is simply the list of commands it issues. Each 607command is a single argument, and therefore probably needs to be quoted. 608When the command to be issued itself contains quotes, you either use a 609different style (single versus double quotes) or you escape the quote 610mark with a back slash (C<'\'>). A simple macro definition would be 611something like 612 613 satpass2> macro defined hi 'echo "Hello world!"' 614 615When a command macro is executed it can be passed arguments. The details 616of how these work will be deferred for the sake of getting on with the 617tutorial, but a case of interest is the fact that C<"$@"> (the quotes 618being part of the syntax) expands to all the arguments passed to the 619macro. 620 621=head2 Multiple Locations 622 623What this topic actually describes is a way to have multiple locations 624on tap, so that if you are going to be at point 'A' from Monday through 625Wednesday, and point 'B' Thursday and Friday you can easily switch 626between them. 627 628The first thing our hypothetical user needs is a command macro to set 629the location to his or her home location. The definition comes from our 630first example: 631 632 satpass2> macro define home \ 633 > "set location '1600 Pennsylvania Ave, Washington DC'" \ 634 > "set latitude 38d53m55.5s longitude -77d2m15.7s" \ 635 > "set height 54.72ft" 636 satpass2> 637 638Normally, this would all have to go on the same line, but 639C<Astro::App::Satpass2> recognizes an end-of-line back slash as a 640continuation mark, so all four lines above are parsed as though they are 641the same line. C<Astro::App::Satpass2> changes the prompt for a 642continuation line, just to keep you on your toes. 643 644Now we need another place to visit -- say, the residence of the Prime 645Minister of Canada: 646 647 satpass2> macro define sussex_drive \ 648 > "set location '24 Sussex Drive, Ottawa, ON'" \ 649 > "set latitude 45.444348 longitude -75.693934" \ 650 > "set height 50m" 651 satpass2> 652 653Now, to switch locations to the Prime Minister's residence, just say 654 655 satpass2> sussex_drive 656 satpass2> 657 satpass2> # and to confirm it, 658 satpass2> location 659 Location: 24 Sussex Drive, Ottawa, ON 660 Latitude 45.4443, longitude -75.6939, height 50 m 661 satpass2> 662 663And to return home, just say 664 665 satpass2> home 666 667Of course, these are really only useful if they are in your 668initialization file. And they can be, with the usual incantation: 669 670 satpass2> save -changes -overwrite 671 672=head2 Temporary Settings 673 674As you recall from the section on L<IRIDIUM FLARES|/IRIDIUM FLARES>, if 675you are trying to imitate the results from Heavens Above you have to 676tweak the default settings a bit. These settings stay tweaked until you 677put them back to their original values. If you always want the tweaks 678when you do Iridium flare predictions, you can put them into a command 679macro along with the flare prediction. Values of settings can be 680localized to a macro (among other things), so that the old values are 681restored when the macro exits. The example could be defined as a command 682macro like this: 683 684 satpass2> macro define iridium_flare \ 685 > 'localize twilight flare_mag_night' \ 686 > 'set twilight -1.8 flare_mag_night -1' \ 687 > 'flare "$@"' 688 satpass2> 689 690Note the use of single quotes rather than double quotes to enclose the 691C<flare> command. In double quotes, or outside quotes altogether, the 692C<$> is magical, and introduces something to be interpolated into the 693command. Exactly what is interpolated depends on what follows the C<$>. 694The C<$@> is replaced by the arguments of the command macro (or 695whatever), but we do not want this to happen until the command macro is 696expanded. Enclosing the C<$@> in double quotes ensures that macro 697arguments containing spaces remain single arguments; without the double 698quotes they would become multiple arguments. 699 700So if you say 701 702 satpass2> iridium_flare -noam 'today 12:00' +3 703 704The C<twilight> and C<flare_mag_night> settings will be changed, the 705flare prediction will be run, and the old C<twilight> and 706C<flare_mag_night> settings will be restored. Because the macro 707arguments get passed to the C<flare> command, the prediction will be for 708the three days starting at noon today, and will exclude flares occurring 709between midnight and the beginning of morning twilight. 710 711Note that B<only> attributes of the C<Astro::App::Satpass2> object 712(those set with a C<set> command) can be localized; attributes of helper 713objects can not be. But you B<can> localize the entire helper object. 714For example, for a temporary change to the 715L<Astro::SpaceTrack|Astro::SpaceTrack> object, 716 717 satpass2> localize spacetrack 718 719inside the appropriate scope. Yes, you can localize outside a command 720macro (or any other localization scope, such as inside a C<source> file 721or a C<begin>-C<end> block), but it does no good to do so, because the 722old value is not restored until you exit, and what good is that? 723 724=head2 Reporting Position 725 726By default, anything that reports a satellite position does it in 727elevation, azimuth and range. You may want some other units, such as 728right ascension and declination. 729 730Deciding what to display is the job of the C<formatter> helper object. 731Normally this is an 732L<Astro::App::Satpass2::Format::Template|Astro::App::Satpass2::Format::Template>, 733and for the full story you should see the documentation to that class. 734 735But there are a number of prepackaged coordinate sets: 736 737 az_rng --------- azimuth (with bearing) and range 738 azel ----------- elevation and azimuth (with bearing) 739 azel_rng ------- elevation, azimuth (with bearing) and range 740 equatorial ----- right ascension and declination 741 equatorial_rng - right ascension, declination and range 742 743By default, you get C<azel_rng>, but you can get any of the others via 744the L<local_coord()|Astro::App::Satpass2::Format/local_coord> 745method of the formatter object. For example, if you want right 746ascension, declination and range, just 747 748 satpass2> formatter local_coord equatorial_rng 749 750=head2 User-defined Position Coordinates 751 752L<Astro::App::Satpass2::Format::Template|Astro::App::Satpass2::Format::Template> 753defines these local coordinates in terms of L<Template-Toolkit|Template> 754templates, so you can add definitions, or change the existing 755definitions, in the same way that you would change one of the reporting 756templates, using that formatter's 757L<template()|Astro::App::Satpass2::Format::Template/template> method. 758For example, to make C<azel> report azimuth first, 759 760 satpass2> formatter template azel <<'EOD' 761 > [% data.azimuth( bearing = 2 ) %] 762 > [%= data.elevation %] 763 > EOD 764 765See the 766L<Astro::App::Satpass2::FormatValue|Astro::App::Satpass2::FormatValue> 767documentation for what format effectors are available. Inside the 768template, the C<data> object will contain the data you want to format. 769 770=head1 ADVANCED TOPICS 771 772=head2 Code Macros 773 774In addition to L<Command Macros|/Command Macros>, a macro can be defined 775using Perl code. This allows one to add new functionality to 776C<Astro::App::Satpass2>, over and above that provided by interactive 777methods. 778 779Code macros are currently unsupported, though it might be better to call 780them experimental. The real situation is that I have been looking for 781ways to plug bits of code into the system, and handling them like macros 782seemed to be the best way. So I knocked something together along those 783lines, and played with it. Further experience may show that the 784interface or the implementation was ill-chosen, or even that there is 785something deeply flawed about the whole idea. The bottom line is that if 786you want this to become supported, you should tell me what you like or 787do not like about it. 788 789In order to implement code macros, a number of previously-private 790methods of L<Astro::App::Satpass2|Astro::App::Satpass2> have been 791exposed. The names of these begin with a double underscore (C<__>), and 792these are documented as unsupported. These will not go away even if code 793macros do, but their calling sequences may change. On the other hand, if 794code macros become fully supported, these will too. 795 796A code macro is simply a Perl subroutine which is called by 797C<Astro::App::Satpass2> more or less as though it were an interactive 798method. In the following discussion, some words are used with particular 799meanings: 800 801=over 802 803=item must 804 805means that the code macro will not work unless this is done; 806 807=item should 808 809means that the code macro will work without doing this, but you might 810not like the results; 811 812=item may 813 814means that the code macro will work without doing this, but you might 815want the functionality described. 816 817=back 818 819Now, Perl subroutines do not live in a vacuum. They in fact live in Perl 820modules; that is, F<.pm> files defining a C<package> whose name reflects 821the path name of the file. A module that defines a code macro can be 822installed like a normal Perl module, but can also live in the F<lib/> 823directory in the user's C<Astro::App::Satpass2> configuration directory 824(which is the default for C<< $satpass2->macro( load => ... ) >>), or 825anywhere if you specify the location via the C<lib> option (e.g. 826C<< $satpass2->macro( load => { lib => something }, ... >>). 827 828In addition to the things that go into making a Perl module, a module 829that provides code macros: 830 831=over 832 833=item must be a subclass of C<Astro::App::Satpass2>; 834 835=item must import C<__arguments()> from C<Astro::App::Satpass2::Utils>. 836 837=back 838 839In order to work as a code macro, a subroutine: 840 841=over 842 843=item must have the C<Verb()> attribute 844 845Subroutine attributes are declared after the name (and signature if any) 846and a colon. 847 848The contents of the parentheses that follow the attribute name will be 849split on white space and used as L<Getopt::Long|Getopt::Long> option 850specifications should these be needed to process the subroutine's 851arguments. 852 853=item may have the C<Configure()> attribute 854 855If this attribute is present, the contents of the parentheses will be 856used to configure the L<Getopt::Long|Getopt::Long> object prior to 857processing the subroutine's arguments. 858 859=item must call C<__arguments()> to unpack C<@_> 860 861This subroutine is imported from 862L<Astro::App::Satpass2::Utils|Astro::App::Satpass2::Utils>. See this 863documentation for details of its use. 864 865=item should report warnings and exceptions properly 866 867In order to have warnings and exceptions be handled consistently with 868the rest of C<Astro::App::Satpass2>, C<< $self->whinge() >> should be 869called instead of C<warn> or C<Carp::carp()>, C<< $self->wail() >> 870should be called instead of C<die> or C<Carp::croak() >>, and 871C<< $self->weep() >> instead of C<Carp::confess() >>. 872 873=item must return human-readable results 874 875This almost goes without saying, since it is the string returned by the 876subroutine which will be displayed. 877 878=back 879 880The arguments passed to your code macro will be, in order, the invoking 881C<Astro::App::Satpass2> object, a reference to the hash generated by 882parsing the arguments, and the non-option arguments, in order. 883 884Your package B<may> define a code macro named C<after_load()>. If this 885is defined, it will be called as soon as the package has been 886successfully loaded. The arguments will be those of the C<macro load> 887itself. 888 889You should be aware that the first argument to your code macro 890subroutine is the C<Astro::App::Satpass2> object that called it. This is 891B<not> reblessed into the package that contains the code macro, so it is 892not an invocant in the usual sense. This has several implications, 893including: 894 895=over 896 897=item * You can not call other code in your module as methods; 898 899This is a direct result of the "invocant" not being blessed into the 900name space of your module. 901 902=item * Your code macro can not be called as a method; 903 904This is because nothing has been done to make it appear in the 905invocant's name space. 906 907=item * Your code can not recurse, even indirectly via a command macro. 908 909This is because all macros become undefined within the scope of their 910own execution, so that a macro of any sort that redefines an interactive 911method has access to the original method. 912 913=back 914 915If you want to call your code macro from inside Perl code, you must call 916it as 917 918 $satpass2->dispatch( your_code_macro => ... ); 919 920and capture any output that is returned. Note that you can still specify 921options either command-line style or as a hash reference in the second 922argument to C<dispatch()>. 923 924You should be cautious about calling C<dispatch()> inside your code 925macro, except perhaps as C<< return $self->dispatch( ... ) >>. If you 926call it internally, you probably need to be sure you concatenate the 927output of your calls, and return that. 928 929A number of methods of L<Astro::App::Satpass2|Astro::App::Satpass2> may 930be useful in your code macro, and in fact were exposed for the use of 931code macros. These include: 932 933=over 934 935=item L<__choose()|Astro::App::Satpass2/__choose> 936 937This can be used to obtain bodies from the observing list or the sky, 938optionally filtered. See especially the C<bodies> and C<sky> options. 939 940=item L<__format_data()|Astro::App::Satpass2/__format_data> 941 942This can be used to pass the raw data generated by your code macro to a 943C<Template-Toolkit> template. It returns the resultant text. 944 945=item L<__parse_angle()|Astro::App::Satpass2/__parse_angle> 946 947This can be used to parse angle arguments. The return is (usually) the 948angle in degrees. 949 950=item L<__parse_distance()|Astro::App::Satpass2/__parse_distance> 951 952This can be used to parse distance arguments. The return is the distance 953in kilometers. 954 955=item L<__parse_time()|Astro::App::Satpass2/__parse_time> 956 957This can be used to parse time arguments. The return is a Perl time. 958 959=back 960 961=head1 AUTHOR 962 963Thomas R. Wyant, III F<wyant at cpan dot org> 964 965=head1 COPYRIGHT AND LICENSE 966 967Copyright (C) 2011-2021 by Thomas R. Wyant, III 968 969This program is free software; you can redistribute it and/or modify it 970under the same terms as Perl 5.10.0. For more details, see the full text 971of the licenses in the directory LICENSES. 972 973This program is distributed in the hope that it will be useful, but 974without any warranty; without even the implied warranty of 975merchantability or fitness for a particular purpose. 976 977=cut 978 979# ex: set textwidth=72 autoindent : 980