}
return if $self->same('lap', $lap_nr);
+ if (defined $self->{lap} && defined $self->track->{race_rounds}
+ && $self->track->{race_rounds} > 0
+ && $self->{lap} > $self->track->{race_rounds}) {
+ $self->{finished} = 1;
+ $self->print_state;
+ }
$self->gui->set_lap($self->{order}, $lap_nr);
if ($self->track->{race_running} && $self->{lap} > 1) {
my $now = $self->{last_finish_time};
if ($self->{in_pit_lane}) {
$self->{state} = 'pit';
- } elsif ($self->{running}) {
- $self->{state} = 'go';
} elsif ($self->{finished}) {
$self->{state} = 'finished';
} elsif ($self->{early_start}) {
$self->set_lap(0);
$self->set_laptime(undef);
+ $self->{finished} = 0;
$self->{in_pit_lane} = 0;
$self->{early_start} = undef;
$self->{last_finish_time} = undef;
$self->gui->set_distance($self->{order}, $time,
$self->{lap_diff}, $self->{time_diff});
+ $self->{grey_diff} = undef;
}
1;
use SCX::CRC;
our $PACKET_SIZE = 9; # 9 bytes + 0x05
-our $LOG_ROTATE = 600;
+our $LOG_FILE_LIMIT = 10_000_000; # bytes
sub new {
my ($class, $args) = @_;
open my $logfh, '>', "$logfile.$log_gen"
or die "Can't open $logfile.$log_gen: $!";
- my $now = gettimeofday;
-
my $self = {
portname => $portname,
fh => $fh,
logfile => $logfile,
logfh => $logfh,
log_gen => $log_gen,
- log_start => $now,
- starttime => $now,
track => $args->{track},
bytes => [],
};
bless $self, $class;
- $self->track->reset;
-
return $self;
}
$self->log_bytes(\@packet, $rv);
$self->track->packet_received($self->{last_read_time});
}
+
if (@bad_bytes) {
while (@bytes && $bytes[0] != 0x55) {
push @bad_bytes, shift @bytes;
@{ $self->{bytes} } = @bytes;
}
-sub log_bytes {
- my ($self, $bytes, $msg) = @_;
-
- return if !@$bytes;
-
- $msg = defined $msg ? ' # ' . $msg : '';
+sub log_print {
+ my ($self, @data) = @_;
- my $now = $self->{last_read_time};
+ my $size = $self->{logfh}->tell;
- if ($now - $self->{log_start} >= $LOG_ROTATE) {
+ if ($size >= $LOG_FILE_LIMIT) {
close $self->{logfh};
$self->{log_gen} = $self->{log_gen} ? 0 : 1;
open my $fh, '>', $self->{logfile} . '.' . $self->{log_gen}
or die "Can't open $self->{logfile}.$self->{log_gen}: $!";
$self->{logfh} = $fh;
- $self->{log_start} = $now;
}
- $self->{logfh}->print(sprintf('% 10.3f', $now - $self->{starttime}),
- (map { sprintf(" %02x", $_) } @$bytes),
- $msg, "\n");
+ $self->{logfh}->print(sprintf('% 10.3f ', $self->{last_read_time}),
+ join(' ', @data, "\n"));
$self->{logfh}->flush;
}
+sub log_bytes {
+ my ($self, $bytes, $msg) = @_;
+
+ return if !@$bytes;
+
+ $msg = defined $msg ? '# ' . $msg : '';
+
+ $self->log_print((map { sprintf("%02x", $_) } @$bytes), $msg);
+}
+
+sub log_cmd {
+ my ($self, @args) = @_;
+
+ $self->log_print('cmd', @args);
+}
+
our %COMMANDS = (
0xAA => \&bus_free_time_packet,
0xCC => \&car_programming_packet,
|| $bytes[4] != 0xAA
|| $bytes[5] != 0xAA;
+ $self->log_cmd('reset');
$self->track->reset;
- return $msg; # FIXME - to be implemented
+ return $msg;
}
sub standings_packet {
push @standings, map { $_ != 0xFF ? $_ & (0x07) : () } @bytes;
- return $msg; # FIXME - to be implemented
+ return $msg; # We do internal standings handling
}
sub lap_time_packet {
|| $bytes[4] & 0x01
|| $bytes[5] & 0x01;
-=comment
- # Moving to internal timekeeping
- my $nonzero = grep { $_ != 0 } @bytes;
-
- my $car = $bytes[0];
- my $round = 256*$bytes[1] + $bytes[2]
- + ($bytes[3] & 2 ? 256 : 0)
- + ($bytes[3] & 1 ? 1 : 0);
- my $time = 256*$bytes[4] + $bytes[5]
- + ($bytes[3] & 8 ? 256 : 0)
- + ($bytes[3] & 4 ? 1 : 0);
- if ($time == 65535) {
- $self->track->car($car)->enter_pit_lane;
- } else {
- $time *= 0.01024;
-
- if ($nonzero) {
- $self->track->car($car)->set_lap($round);
- $self->track->car($car)->set_laptime($time);
- } else {
- # FIXME - probably reset race time or whatever
- # all-zeros packet is sent after the race setup
- }
- }
-=cut
-
return $msg;
}
-
sub race_setup_packet {
my ($self, @bytes) = @_;
|| $bytes[4] != 0xFF
|| $bytes[5] != 0xFF;
- $self->track->race_setup($bytes[0] == 0x00
+ my $rounds = $bytes[0] == 0x00
? 0
: ($bytes[1] & 0x0F) * 256
+ ($bytes[2] & 0x0F) * 16
- + ($bytes[3] & 0x0F));
+ + ($bytes[3] & 0x0F);
+
+ $self->log_cmd('race_setup', $rounds);
+ $self->track->race_setup($rounds);
return $msg;
}
-
sub fuel_level_packet {
my ($self, @bytes) = @_;
$bytes[2] >> 4, $bytes[2] & 0x0f,
);
+ $self->log_cmd('fuel', @fuel);
for my $car (0..5) {
$self->track->car($car)->set_fuel($fuel[$car]);
}
|| $bytes[4] != 0xFF
|| $bytes[5] != 0xFF;
+ $self->log_cmd('qualification_start');
$self->track->qualification_start;
return $msg;
|| $bytes[4] != 0xFF
|| $bytes[5] != 0xFF;
+ $self->log_cmd('race_end');
$self->track->race_end;
return $msg;
|| $bytes[4] != 0xAA
|| $bytes[5] != 0xAA;
+ $self->log_cmd('race_start');
$self->track->race_start;
return $msg;
push @cars_finished, $i if $byte == 0xE7;
}
+ $self->log_cmd('finish_line', $regular, @cars_finished);
$self->track->finish_line(
$self->{last_read_time},
$regular,
my $msg = 'Strange controller_status packet'
if $fail;
- my @fuel = (
- $bytes[1] >> 4, $bytes[1] & 0x0f,
- $bytes[2] >> 4, $bytes[2] & 0x0f,
- $bytes[3] >> 4, $bytes[3] & 0x0f,
- );
+ my @log_data;
for my $car (0..5) {
my $byte = $bytes[$car];
if ($byte == 0xAA) {
$self->track->car($car)->set_throttle(undef, undef,
$self->{last_read_time});
+ push @log_data, 'undef', '0';
next;
}
my $backbutton = !($byte & 0x10);
my $throttle = $byte & 0x0f;
+ push @log_data, $throttle, $backbutton ? 1 : 0;
$self->track->car($car)->set_throttle($throttle, $backbutton,
$self->{last_read_time});
$self->track->car($car)->set_light($light);
}
+ $self->log_cmd('throttle', @log_data);
+
return $msg;
}