File Coverage

blib/lib/Rinchi/CIGIPP/IGControl.pm
Criterion Covered Total %
statement 65 101 64.3
branch 11 32 34.3
condition 5 18 27.7
subroutine 18 20 90.0
pod 16 16 100.0
total 115 187 61.5


line stmt bran cond sub pod time code
1             #
2             # Rinchi Common Image Generator Interface for Perl
3             # Class Identifier: f78aaaf6-200e-11de-bda1-001c25551abc
4             # Author: Brian M. Ames
5             #
6              
7             package Rinchi::CIGIPP::IGControl;
8              
9 1     1   30 use 5.006;
  1         5  
  1         36  
10 1     1   5 use strict;
  1         2  
  1         28  
11 1     1   6 use warnings;
  1         2  
  1         28  
12 1     1   5 use Carp;
  1         2  
  1         5037  
13              
14             require Exporter;
15              
16             our @ISA = qw(Exporter);
17              
18             # Items to export into callers namespace by default. Note: do not export
19             # names by default without a very good reason. Use EXPORT_OK instead.
20             # Do not simply export all your public functions/methods/constants.
21              
22             # This allows declaration use Rinchi::CIGI::AtmosphereControl ':all';
23             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
24             # will save memory.
25             our %EXPORT_TAGS = ( 'all' => [ qw(
26            
27             ) ] );
28              
29             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
30              
31             our @EXPORT = qw(
32            
33             );
34              
35             our $VERSION = '0.01';
36              
37             # Preloaded methods go here.
38              
39             =head1 NAME
40              
41             Rinchi::CIGIPP::IGControl - Perl extension for the Common Image Generator
42             Interface - IGControl data packet.
43             data packet.
44             =head1 SYNOPSIS
45              
46             use Rinchi::CIGIPP::IGControl;
47             my $ig_ctl = Rinchi::CIGIPP::IGControl->new();
48              
49             $packet_type = $ig_ctl->packet_type();
50             $packet_size = $ig_ctl->packet_size();
51             $major_version = $ig_ctl->major_version();
52             $database_number = $ig_ctl->database_number(65);
53             $minor_version = $ig_ctl->minor_version();
54             $extrapolation_enable = $ig_ctl->extrapolation_enable(Rinchi::CIGIPP->Disable);
55             $timestamp_valid = $ig_ctl->timestamp_valid(Rinchi::CIGIPP->Invalid);
56             $ig_mode = $ig_ctl->ig_mode(Rinchi::CIGIPP->Standby);
57             $magic_number = $ig_ctl->magic_number();
58             $host_frame_number = $ig_ctl->host_frame_number(38591);
59             $timestamp = $ig_ctl->timestamp(52141);
60             $last_igframe_number = $ig_ctl->last_igframe_number(47470);
61              
62             =head1 DESCRIPTION
63              
64             The IG Control packet is used to control the IG's operational mode, database
65             loading, and timing correction. This must be the first packet in each
66             Host-to-IG message, and every Host-to-IG message must contain exactly one IG
67             Control packet. If more than one is encountered during a given frame, the
68             resulting IG behavior is undefined. The IG Control packet allows the Host to
69             control the loading of terrain. Each database is associated with a number from
70             1 to 127. The Host will set the Database Number attribute to the appropriate
71             value to direct the IG to begin reading the corresponding database into memory.
72              
73             The IG will indicate that the database is being loaded by negating the value
74             and placing it in the Database Number attribute of the Start of Frame packet.
75             The Host will then acknowledge this change by setting the Database Number
76             attribute of the IG Control packet to zero (0). Because the IG's resources may
77             be devoted to disk I/O and other functions, the Host should ideally send only
78             IG Control packets at this time.
79              
80             After the IG receives the acknowledgement, it will signal the completion of the
81             database load by setting the Database Number attribute of the Start of Frame
82             packet to the positive database number. The IG is now considered mission-ready
83             and can receive mission data from the Host.
84              
85             Note that the IG will ignore the Database Number attribute while in
86             Reset/Standby mode.
87              
88             When using a global database, the IG will set the Database Number of the Start
89             of Frame packet to zero (0). When the Host detects a zero in this attribute, it
90             should in turn set the Database Number attribute of the IG Control packet to
91             zero (0).
92              
93             =head2 EXPORT
94              
95             None by default.
96              
97             #==============================================================================
98              
99             =item new $ig_ctl = Rinchi::CIGIPP::IGControl->new()
100              
101             Constructor for Rinchi::IGControl.
102              
103             =cut
104              
105             sub new {
106 1     1 1 598 my $class = shift;
107 1   33     10 $class = ref($class) || $class;
108              
109 1         22 my $self = {
110             '_Buffer' => '',
111             '_ClassIdent' => 'f78aaaf6-200e-11de-bda1-001c25551abc',
112             '_Pack' => 'CCCcCCSIIII',
113             '_Swap1' => 'CCCcCCvVVVV',
114             '_Swap2' => 'CCCcCCnNNNN',
115             'packetType' => 1,
116             'packetSize' => 24,
117             'majorVersion' => 3,
118             'databaseNumber' => 0,
119             '_bitfields1' => 48, # Includes bitfields minorVersion, extrapolationEnable, timestampValid, and igMode.
120             '_unused1' => 0,
121             'minorVersion' => 3,
122             'extrapolationEnable' => 0,
123             'timestampValid' => 0,
124             'igMode' => 0,
125             'magicNumber' => 32768,
126             'hostFrameNumber' => 0,
127             'timestamp' => 0,
128             'lastIGFrameNumber' => 0,
129             '_unused2' => 0,
130             };
131              
132 1 50       5 if (@_) {
133 0 0       0 if (ref($_[0]) eq 'ARRAY') {
    0          
134 0         0 $self->{'_Buffer'} = $_[0][0];
135             } elsif (ref($_[0]) eq 'HASH') {
136 0         0 foreach my $attr (keys %{$_[0]}) {
  0         0  
137 0 0       0 $self->{"_$attr"} = $_[0]->{$attr} unless ($attr =~ /^_/);
138             }
139             }
140             }
141              
142 1         4 bless($self,$class);
143 1         4 return $self;
144             }
145              
146             #==============================================================================
147              
148             =item sub packet_type()
149              
150             $value = $ig_ctl->packet_type();
151              
152             Data Packet Identifier.
153              
154             This attribute identifies this data packet as the IG Control packet. The value
155             of this attribute must be 1.
156              
157             =cut
158              
159             sub packet_type() {
160 1     1 1 8 my ($self) = @_;
161 1         8 return $self->{'packetType'};
162             }
163              
164             #==============================================================================
165              
166             =item sub packet_size()
167              
168             $value = $ig_ctl->packet_size();
169              
170             Data Packet Size.
171              
172             This attribute indicates the number of bytes in this data packet. The value of
173             this attribute must be 24.
174              
175             =cut
176              
177             sub packet_size() {
178 1     1 1 6 my ($self) = @_;
179 1         4 return $self->{'packetSize'};
180             }
181              
182             #==============================================================================
183              
184             =item sub major_version()
185              
186             $value = $ig_ctl->major_version();
187              
188             Major Version.
189              
190             This attribute indicates the major version of the CIGI interface that is
191             currently being used by the Host. The IG can use this number to determine
192             concurrency. The Host must set the value of this attribute to 3.
193              
194             =cut
195              
196             sub major_version() {
197 1     1 1 6 my ($self) = @_;
198 1         3 return $self->{'majorVersion'};
199             }
200              
201             #==============================================================================
202              
203             =item sub database_number([$newValue])
204              
205             $value = $ig_ctl->database_number($newValue);
206              
207             Database Number.
208              
209             This attribute is used to initiate a database load on the IG. Setting this
210             attribute to a non-zero value will cause the IG to begin loading the database
211             that corresponds to that value. If the number corresponds to the current
212             database, the database will be reloaded. The IG will indicate that the database
213             is being loaded by negating the value and placing it in the Database Number
214             attribute of the Start of Frame packet. When the Host receives this
215             notification, it should set the Database Number attribute of the IG Control
216             packet to zero (0) to prevent continuous reloading of the database on the IG.
217             The IG will ignore this attribute while in Reset/Standby mode.
218              
219             =cut
220              
221             sub database_number() {
222 1     1 1 6 my ($self,$nv) = @_;
223 1 50       4 if (defined($nv)) {
224 1         4 $self->{'databaseNumber'} = $nv;
225             }
226 1         3 return $self->{'databaseNumber'};
227             }
228              
229             #==============================================================================
230              
231             =item sub minor_version()
232              
233             $value = $ig_ctl->minor_version();
234              
235             Minor Version.
236              
237             This attribute indicates the minor version of the CIGI interface that is
238             currently being used by the Host. The IG can use this number to determine concurrency.
239              
240             =cut
241              
242             sub minor_version() {
243 1     1 1 6 my ($self) = @_;
244 1         4 return (($self->{'_bitfields1'} & 0xF0) >> 4);
245             }
246              
247             #==============================================================================
248              
249             =item sub extrapolation_enable([$newValue])
250              
251             $value = $ig_ctl->extrapolation_enable($newValue);
252              
253             Extrapolation/Interpolation Enable.
254              
255             This attribute specifies whether any "dead reckoning" or other entity
256             extrapolation or interpolation algorithms are enabled.
257              
258             If this attribute is set to Disable (0), then extrapolation or interpolation is
259             disabled for all entities.
260              
261             If this attribute is set to Enable (1), then extrapolation or interpolation is
262             determined on a per-entity basis by the Linear Extrapolation/Interpolation
263             Enable flag in the Entity Control packet.
264              
265             Disable 0
266             Enable 1
267              
268             =cut
269              
270             sub extrapolation_enable() {
271 1     1 1 4 my ($self,$nv) = @_;
272 1 50       4 if (defined($nv)) {
273 1 50 33     7 if (($nv==0) or ($nv==1)) {
274 1         3 $self->{'extrapolationEnable'} = $nv;
275 1         3 $self->{'_bitfields1'} |= ($nv << 3) &0x08;
276             } else {
277 0         0 carp "extrapolation_enable must be 0 (Disable), or 1 (Enable).";
278             }
279             }
280 1         3 return (($self->{'_bitfields1'} & 0x08) >> 3);
281             }
282              
283             #==============================================================================
284              
285             =item sub timestamp_valid([$newValue])
286              
287             $value = $ig_ctl->timestamp_valid($newValue);
288              
289             Timestamp Valid.
290              
291             This attribute indicates whether the Timestamp attribute contains a valid
292             value. Because the Timestamp attribute is required for asynchronous operation,
293             Timestamp Valid must be set to Valid (1) in this mode.
294              
295             Invalid 0
296             Valid 1
297              
298             =cut
299              
300             sub timestamp_valid() {
301 1     1 1 2 my ($self,$nv) = @_;
302 1 50       6 if (defined($nv)) {
303 1 50 33     5 if (($nv==0) or ($nv==1)) {
304 1         3 $self->{'timestampValid'} = $nv;
305 1         2 $self->{'_bitfields1'} |= ($nv << 2) &0x04;
306             } else {
307 0         0 carp "timestamp_valid must be 0 (Invalid), or 1 (Valid).";
308             }
309             }
310 1         4 return (($self->{'_bitfields1'} & 0x04) >> 2);
311             }
312              
313             #==============================================================================
314              
315             =item sub ig_mode([$newValue])
316              
317             $value = $ig_ctl->ig_mode($newValue);
318              
319             IG Mode.
320              
321             This attribute dictates the IG's operational mode. The Host can initiate a mode
322             change by setting this attribute to the desired mode. When the IG completes the
323             mode change, it will set the IG Mode attribute in the Start of Frame packet accordingly.
324              
325             Reset 0
326             Standby 1
327             Operate 1
328             Debug 2
329              
330             =cut
331              
332             sub ig_mode() {
333 1     1 1 3 my ($self,$nv) = @_;
334 1 50       5 if (defined($nv)) {
335 1 50 33     9 if (($nv==0) or ($nv==1) or ($nv==1) or ($nv==2)) {
      33        
      0        
336 1         3 $self->{'igMode'} = $nv;
337 1         2 $self->{'_bitfields1'} |= $nv &0x03;
338             } else {
339 0         0 carp "ig_mode must be 0 (Reset), 1 (Standby), 1 (Operate), or 2 (Debug).";
340             }
341             }
342 1         4 return ($self->{'_bitfields1'} & 0x03);
343             }
344              
345             #==============================================================================
346              
347             =item sub magic_number()
348              
349             $value = $ig_ctl->magic_number();
350              
351             Byte Swap Magic Number.
352              
353             This attribute is used by the IG to determine whether it needs to byte-swap
354             incoming data. The Host must set this value to 8000h, or 32768.
355              
356             =cut
357              
358             sub magic_number() {
359 1     1 1 6 my ($self) = @_;
360 1         3 return $self->{'magicNumber'};
361             }
362              
363             #==============================================================================
364              
365             =item sub host_frame_number([$newValue])
366              
367             $value = $ig_ctl->host_frame_number($newValue);
368              
369             Host Frame Number.
370              
371             This attribute uniquely identifies a data frame on the Host. The Host should
372             increment this value by one (1) for each successive message.
373              
374             =cut
375              
376             sub host_frame_number() {
377 1     1 1 5 my ($self,$nv) = @_;
378 1 50       5 if (defined($nv)) {
379 1         3 $self->{'hostFrameNumber'} = $nv;
380             }
381 1         3 return $self->{'hostFrameNumber'};
382             }
383              
384             #==============================================================================
385              
386             =item sub timestamp([$newValue])
387              
388             $value = $ig_ctl->timestamp($newValue);
389              
390             Timestamp.
391              
392             This attribute indicates the number of 10μs "ticks" since some initial
393             reference time. This will enable the IG to correct for latencies. The 10μs unit
394             allows the simulation to run for approximately 12 hours before a timestamp
395             rollover occurs. The IG software should contain logic to detect and correct for
396             rollover. The use of this attribute is required for asynchronous operation. The
397             use of this attribute is optional for synchronous operation. If this attribute
398             does not contain a valid timestamp, the Timestamp Valid attribute should be set
399             to zero (0).
400              
401             =cut
402              
403             sub timestamp() {
404 1     1 1 4 my ($self,$nv) = @_;
405 1 50       4 if (defined($nv)) {
406 1         3 $self->{'timestamp'} = $nv;
407             }
408 1         3 return $self->{'timestamp'};
409             }
410              
411             #==============================================================================
412              
413             =item sub last_igframe_number([$newValue])
414              
415             $value = $ig_ctl->last_igframe_number($newValue);
416              
417             Last IG Frame Number.
418              
419             This attribute contains the value of the IG Frame Number attribute in the last
420             Start of Frame packet received from the IG. This attribute serves as an
421             acknowledgement that the Host received the last message.
422              
423             =cut
424              
425             sub last_igframe_number() {
426 1     1 1 5 my ($self,$nv) = @_;
427 1 50       4 if (defined($nv)) {
428 1         3 $self->{'lastIGFrameNumber'} = $nv;
429             }
430 1         3 return $self->{'lastIGFrameNumber'};
431             }
432              
433             #==========================================================================
434              
435             =item sub pack()
436              
437             $value = $ig_ctl->pack();
438              
439             Returns the packed data packet.
440              
441             =cut
442              
443             sub pack($) {
444 1     1 1 4 my $self = shift ;
445            
446 1         12 $self->{'_Buffer'} = CORE::pack($self->{'_Pack'},
447             $self->{'packetType'},
448             $self->{'packetSize'},
449             $self->{'majorVersion'},
450             $self->{'databaseNumber'},
451             $self->{'_bitfields1'}, # Includes bitfields minorVersion, extrapolationEnable, timestampValid, and igMode.
452             $self->{'_unused1'},
453             $self->{'magicNumber'},
454             $self->{'hostFrameNumber'},
455             $self->{'timestamp'},
456             $self->{'lastIGFrameNumber'},
457             $self->{'_unused2'},
458             );
459              
460 1         5 return $self->{'_Buffer'};
461             }
462              
463             #==========================================================================
464              
465             =item sub unpack()
466              
467             $value = $ig_ctl->unpack();
468              
469             Unpacks the packed data packet.
470              
471             =cut
472              
473             sub unpack($) {
474 0     0 1   my $self = shift @_;
475              
476 0 0         if (@_) {
477 0           $self->{'_Buffer'} = shift @_;
478             }
479 0           my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k) = CORE::unpack($self->{'_Pack'},$self->{'_Buffer'});
480 0           $self->{'packetType'} = $a;
481 0           $self->{'packetSize'} = $b;
482 0           $self->{'majorVersion'} = $c;
483 0           $self->{'databaseNumber'} = $d;
484 0           $self->{'_bitfields1'} = $e; # Includes bitfields minorVersion, extrapolationEnable, timestampValid, and igMode.
485 0           $self->{'_unused1'} = $f;
486 0           $self->{'magicNumber'} = $g;
487 0           $self->{'hostFrameNumber'} = $h;
488 0           $self->{'timestamp'} = $i;
489 0           $self->{'lastIGFrameNumber'} = $j;
490 0           $self->{'_unused2'} = $k;
491              
492 0           $self->{'minorVersion'} = $self->minor_version();
493 0           $self->{'extrapolationEnable'} = $self->extrapolation_enable();
494 0           $self->{'timestampValid'} = $self->timestamp_valid();
495 0           $self->{'igMode'} = $self->ig_mode();
496              
497 0           return $self->{'_Buffer'};
498             }
499              
500             #==========================================================================
501              
502             =item sub byte_swap()
503              
504             $obj_name->byte_swap();
505              
506             Byte swaps the packed data packet.
507              
508             =cut
509              
510             sub byte_swap($) {
511 0     0 1   my $self = shift @_;
512            
513 0 0         if (@_) {
514 0           $self->{'_Buffer'} = shift @_;
515             } else {
516 0           $self->pack();
517             }
518 0           my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k) = CORE::unpack($self->{'_Swap1'},$self->{'_Buffer'});
519              
520 0           $self->{'_Buffer'} = CORE::pack($self->{'_Swap2'},$a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k);
521 0           $self->unpack();
522              
523 0           return $self->{'_Buffer'};
524             }
525              
526             1;
527             __END__