From e5ecd9d0a9df93798930c678f4f4aa58e0e6a10a Mon Sep 17 00:00:00 2001 From: "Jan \"Yenya\" Kasprzak" Date: Sun, 12 Dec 2010 15:15:25 +0100 Subject: [PATCH] More fixes. --- SCX/Car.pm | 10 ++- SCX/Reader.pm | 98 ++++++++++++--------------- SCX/Track.pm | 24 +++++-- gui.pl | 2 +- img/{state-stop.svg => state-pit.svg} | 0 5 files changed, 69 insertions(+), 65 deletions(-) rename img/{state-stop.svg => state-pit.svg} (100%) diff --git a/SCX/Car.pm b/SCX/Car.pm index b6466be..91a244d 100644 --- a/SCX/Car.pm +++ b/SCX/Car.pm @@ -100,6 +100,12 @@ sub set_lap { } 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}; @@ -192,8 +198,6 @@ sub print_state { if ($self->{in_pit_lane}) { $self->{state} = 'pit'; - } elsif ($self->{running}) { - $self->{state} = 'go'; } elsif ($self->{finished}) { $self->{state} = 'finished'; } elsif ($self->{early_start}) { @@ -210,6 +214,7 @@ sub reset { $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; @@ -270,6 +275,7 @@ sub recalc_distance { $self->gui->set_distance($self->{order}, $time, $self->{lap_diff}, $self->{time_diff}); + $self->{grey_diff} = undef; } 1; diff --git a/SCX/Reader.pm b/SCX/Reader.pm index 59f7ca3..5422a4b 100644 --- a/SCX/Reader.pm +++ b/SCX/Reader.pm @@ -11,7 +11,7 @@ use POSIX; 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) = @_; @@ -33,24 +33,18 @@ sub new { 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; } @@ -100,6 +94,7 @@ sub read { $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; @@ -110,30 +105,40 @@ sub read { @{ $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, @@ -199,9 +204,10 @@ sub reset_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 { @@ -219,7 +225,7 @@ 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 { @@ -233,36 +239,9 @@ 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) = @_; @@ -274,16 +253,18 @@ sub race_setup_packet { || $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) = @_; @@ -302,6 +283,7 @@ sub fuel_level_packet { $bytes[2] >> 4, $bytes[2] & 0x0f, ); + $self->log_cmd('fuel', @fuel); for my $car (0..5) { $self->track->car($car)->set_fuel($fuel[$car]); } @@ -328,6 +310,7 @@ sub qualification_packet { || $bytes[4] != 0xFF || $bytes[5] != 0xFF; + $self->log_cmd('qualification_start'); $self->track->qualification_start; return $msg; @@ -345,6 +328,7 @@ sub end_of_race_packet { || $bytes[4] != 0xFF || $bytes[5] != 0xFF; + $self->log_cmd('race_end'); $self->track->race_end; return $msg; @@ -362,6 +346,7 @@ sub race_start_packet { || $bytes[4] != 0xAA || $bytes[5] != 0xAA; + $self->log_cmd('race_start'); $self->track->race_start; return $msg; @@ -409,6 +394,7 @@ sub finish_line_packet { push @cars_finished, $i if $byte == 0xE7; } + $self->log_cmd('finish_line', $regular, @cars_finished); $self->track->finish_line( $self->{last_read_time}, $regular, @@ -432,11 +418,7 @@ sub controller_status_packet { 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]; @@ -444,6 +426,7 @@ sub controller_status_packet { if ($byte == 0xAA) { $self->track->car($car)->set_throttle(undef, undef, $self->{last_read_time}); + push @log_data, 'undef', '0'; next; } @@ -451,11 +434,14 @@ sub controller_status_packet { 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; } diff --git a/SCX/Track.pm b/SCX/Track.pm index c5d4640..b71257e 100644 --- a/SCX/Track.pm +++ b/SCX/Track.pm @@ -41,6 +41,7 @@ sub race_start { return if $self->{race_running} || $self->{start_in_progress} || $self->{qualification_running}; + $self->{round} = 0; $self->{race_running} = 0; $self->{start_in_progress} = 1; $self->{semaphore} = 0; @@ -207,18 +208,29 @@ sub recalc_order { sub finish_line { my ($self, $time, $regular, @cars) = @_; - my @processed; + my %processed; + my $was_processed; + for my $car (@cars) { - push @processed, $car - if $self->car($car)->finish_line($time, $regular); + if ($self->car($car)->finish_line($time, $regular)) { + $processed{$car} = 1; + $was_processed = 1; + } } - if (@processed) { + + if ($was_processed) { my ($first_car, $lap_max, $time_min) = $self->recalc_order($time); - for my $car (@processed) { - $self->car($car)->recalc_distance($lap_max, $time_min); + for my $car (0..5) { + if ($processed{$car}) { + $self->car($car)->recalc_distance( + $lap_max, $time_min + ); + } else { + #$self->car($car)->greyout_distance; + } } } } diff --git a/gui.pl b/gui.pl index 3f74cc4..c632a8c 100755 --- a/gui.pl +++ b/gui.pl @@ -10,7 +10,7 @@ use SCX::GUI; use SCX::Track; use SCX::Reader; -my $gui = SCX::GUI->new({ img_height => 80 }); +my $gui = SCX::GUI->new({ img_height => 120 }); my $track = SCX::Track->new({ gui => $gui }); my $reader; diff --git a/img/state-stop.svg b/img/state-pit.svg similarity index 100% rename from img/state-stop.svg rename to img/state-pit.svg -- 2.43.5