-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
9 changed files
with
464 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package Module::Reload; | ||
$Module::Reload::VERSION = '1.11'; | ||
use 5.006; | ||
use strict; | ||
use warnings; | ||
|
||
our $Debug = 0; | ||
our %Stat; | ||
|
||
sub check { | ||
my $c=0; | ||
|
||
foreach my $entry (map { [ $_, $INC{$_} ] } keys %INC) { | ||
my($key,$file) = @$entry; | ||
|
||
# If the require'ing of a file failed, but was caught by eval, | ||
# then we end up with a value of undef in %INC. Skip those. | ||
next unless defined($file); | ||
|
||
next if $file eq $INC{"Module/Reload.pm"}; #too confusing | ||
local $^W = 0; | ||
my $mtime = (stat $file)[9]; | ||
$Stat{$file} = $^T unless defined $Stat{$file}; | ||
|
||
if ($Debug >= 3) { | ||
warn "Module::Reload: stat '$file' got $mtime >? $Stat{$file}\n"; | ||
} | ||
|
||
if ($mtime > $Stat{$file}) { | ||
delete $INC{$key}; | ||
eval { | ||
local $SIG{__WARN__} = \&warn; | ||
require $key; | ||
}; | ||
if ($@) { | ||
warn "Module::Reload: error during reload of '$key': $@\n"; | ||
} | ||
elsif ($Debug) { | ||
if ($Debug == 1) { | ||
warn "Module::Reload: process $$ reloaded '$key'\n"; | ||
} | ||
if ($Debug >= 2) { | ||
warn("Module::Reload: process $$ reloaded '$key' (\@INC=". | ||
join(', ',@INC).")\n"); | ||
} | ||
} | ||
++$c; | ||
} | ||
$Stat{$file} = $mtime; | ||
} | ||
$c; | ||
} | ||
|
||
1; | ||
|
||
__END__ | ||
=head1 NAME | ||
Module::Reload - Reload %INC files when updated on disk | ||
=head1 SYNOPSIS | ||
Module::Reload->check; | ||
=head1 DESCRIPTION | ||
When Perl pulls a file via C<require>, it stores the filename in the | ||
global hash C<%INC>. The next time Perl tries to C<require> the same | ||
file, it sees the file in C<%INC> and does not reload from disk. This | ||
module's handler iterates over C<%INC> and reloads the file if it has | ||
changed on disk. | ||
Set $Module::Reload::Debug to enable debugging output. | ||
=head1 BUGS | ||
A growing number of pragmas (C<base>, C<fields>, etc.) assume that | ||
they are loaded once only. When you reload the same file again, they | ||
tend to become confused and break. If you feel motivated to submit | ||
patches for these problems, I would encourage that. | ||
=head1 SEE ALSO | ||
L<Module::Reload::Selective> is like this module, but lets you | ||
control which modules will be reloaded. | ||
L<again> provides a slightly different mechanism for reloading | ||
changed modules, where you have to explicitly decide which modules to reload. | ||
L<Apache2::Reload> (or L<Apache::Reload> if you're still using Apache 1). | ||
L<perldoc require|http://perldoc.perl.org/functions/require.html> | ||
for details of how C<require> works. | ||
=head1 REPOSITORY | ||
L<https://github.com/neilb/Module-Reload> | ||
=head1 AUTHOR | ||
Doug MacEachern & Joshua Pritikin | ||
Now maintained by Neil Bowers E<lt>[email protected]E<gt> | ||
=head1 COPYRIGHT AND LICENSE | ||
This software is copyright (c) 1997-1998 Doug MacEachern & Joshua Pritikin. | ||
This is free software; you can redistribute it and/or modify it under | ||
the same terms as the Perl 5 programming language system itself. | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
package PIDController; | ||
$PIDController::VERSION = '0.001'; | ||
# PID Controller in Perl by Christian Fenzl | ||
# Based on Python code from Caner Durmusoglu (https://github.com/ivmech/ivPID/blob/master/PID.py) | ||
use strict; | ||
use warnings; | ||
use Time::HiRes; | ||
|
||
sub new { | ||
# Class PIDController | ||
|
||
my $class = shift; | ||
|
||
if (@_ % 2) { | ||
Carp::croak "Illegal parameter list has odd number of values\n" . join("\n", @_) . "\n"; | ||
} | ||
|
||
my %params = @_; | ||
my $self = {}; | ||
|
||
$self->{Kp} = $params{P}; | ||
$self->{Ki} = $params{I}; | ||
$self->{Kd} = $params{D}; | ||
|
||
$self->{sample_time} = 0; | ||
$self->{current_time} = Time::HiRes::gettimeofday(); | ||
$self->{last_time} = $self->{current_time}; | ||
|
||
bless $self, $class; | ||
|
||
$self->clear(); | ||
|
||
return $self; | ||
|
||
} | ||
|
||
sub clear { | ||
# Clears PID computations and coefficients | ||
|
||
my $self = shift; | ||
$self->{SetPoint} = 0.0; | ||
$self->{PTerm} = 0.0; | ||
$self->{ITerm} = 0.0; | ||
$self->{DTerm} = 0.0; | ||
$self->{last_error} = 0.0; | ||
|
||
# Windup Guard | ||
$self->{int_error} = 0.0; | ||
$self->{windup_guard} = 20.0; | ||
|
||
$self->{output} = 0.0; | ||
return $self->{output}; | ||
|
||
} | ||
|
||
sub update { | ||
# Calculates PID value for given reference feedback | ||
# u(t) = K_p e(t) + K_i \int_{0}^{t} e(t)dt + K_d {de}/{dt} | ||
# Test PID with Kp=1.2, Ki=1, Kd=0.001 | ||
|
||
my $self = shift; | ||
my $feedback_value = shift; | ||
my $current_time = shift; | ||
|
||
my $error = defined $self->{setPoint} ? $self->{setPoint} - $feedback_value : -$feedback_value; | ||
|
||
$self->{current_time} = Time::HiRes::gettimeofday(); | ||
my $delta_time = $self->{current_time} - $self->{last_time}; | ||
my $delta_error = $error - $self->{last_error}; | ||
|
||
if( $delta_time >= $self->{sample_time}) { | ||
$self->{PTerm} = $self->{Kp} * $error; | ||
$self->{ITerm} += $error * $delta_time; | ||
|
||
if( $self->{ITerm} < -$self->{windup_guard} ) { | ||
$self->{ITerm} = -$self->{windup_guard}; | ||
} elsif ($self->{ITerm} > $self->{windup_guard} ) { | ||
$self->{ITerm} = $self->{windup_guard}; | ||
} | ||
|
||
$self->{DTerm} = 0; | ||
if ($delta_time > 0 ) { | ||
$self->{DTerm} = $delta_error / $delta_time; | ||
} | ||
|
||
# Remember last time and last error for next calculation | ||
$self->{last_time} = $self->{current_time}; | ||
$self->{last_error} = $error; | ||
|
||
$self->{output} = $self->{PTerm} + ($self->{Ki} * $self->{ITerm}) + ($self->{Kd} * $self->{DTerm}); | ||
return $self->{output}; | ||
|
||
|
||
} | ||
} | ||
|
||
sub setKp { | ||
# Determines how aggressively the PID reacts to the current error with setting Proportional Gain | ||
my $self = shift; | ||
my $proportional_gain = shift; | ||
$self->{Kp} = $proportional_gain; | ||
} | ||
|
||
sub setKi { | ||
# Determines how aggressively the PID reacts to the current error with setting Integral Gain | ||
my $self = shift; | ||
my $integral_gain = shift; | ||
$self->{Ki} = $integral_gain; | ||
} | ||
|
||
sub setKd { | ||
# Determines how aggressively the PID reacts to the current error with setting Derivative Gain | ||
my $self = shift; | ||
my $derivative_gain = shift; | ||
$self->{Kd} = $derivative_gain; | ||
} | ||
|
||
sub setWindup { | ||
# Integral windup, also known as integrator windup or reset windup, | ||
# refers to the situation in a PID feedback controller where | ||
# a large change in setpoint occurs (say a positive change) | ||
# and the integral terms accumulates a significant error | ||
# during the rise (windup), thus overshooting and continuing | ||
# to increase as this accumulated error is unwound | ||
# (offset by errors in the other direction). | ||
# The specific problem is the excess overshooting. | ||
|
||
my $self = shift; | ||
my $windup = shift; | ||
$self->{windup_guard} = $windup; | ||
} | ||
|
||
sub setSampleTime { | ||
# PID that should be updated at a regular interval. | ||
# Based on a pre-determined sampe time, the PID decides if it should compute or return immediately. | ||
|
||
my $self = shift; | ||
my $sample_time = shift; | ||
$self->{sample_time} = $sample_time; | ||
} | ||
|
||
|
||
|
||
|
||
|
||
# === FINALLY 1 === | ||
1; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package Proc::CPUUsage; | ||
$Proc::CPUUsage::VERSION = '1.002'; | ||
use strict; | ||
use warnings; | ||
use BSD::Resource qw( getrusage ); | ||
use Time::HiRes qw( gettimeofday tv_interval ); | ||
|
||
sub new { | ||
my $class = shift; | ||
|
||
return bless [ [gettimeofday()], _cpu_time(), 0 ], $class; | ||
} | ||
|
||
sub usage { | ||
my $self = $_[0]; | ||
my ($t0, $r0, $u0) = @$self; | ||
return unless defined $r0; | ||
|
||
my ($dt, $dr, $t1, $r1, $u1); | ||
$t1 = [gettimeofday()]; | ||
$dt = tv_interval($t0, $t1); | ||
$self->[0] = $t1; | ||
|
||
$r1 = _cpu_time(); | ||
$dr = $r1 - $r0; | ||
$self->[1] = $r1; | ||
|
||
$u1 = $dt == 0 ? $u0 : $dr/$dt; | ||
$self->[2] = $u1; | ||
|
||
return $u1; | ||
} | ||
|
||
sub _cpu_time { | ||
my ($utime, $stime) = getrusage(); | ||
return unless defined $utime && defined $stime; | ||
return $utime+$stime; | ||
} | ||
|
||
1; | ||
|
||
__END__ | ||
=encoding utf8 | ||
=head1 NAME | ||
Proc::CPUUsage - measures the percentage of CPU the current process is using | ||
=head1 VERSION | ||
version 1.002 | ||
=head1 SYNOPSIS | ||
my $cpu = Proc::CPUUsage->new; | ||
my $usage1 = $cpu->usage; ## returns usage since new() | ||
my $usage2 = $cpu->usage; ## returns usage since last usage() | ||
... | ||
=head1 DESCRIPTION | ||
This module allows you to measure how much CPU your perl process is | ||
using. | ||
The construction of the object defines the inital values. Each call to | ||
L</"usage()"> returns the CPU usage since the last call to L</"new()"> or | ||
L</"usage()">. | ||
The value returned is normalised between 0 and 1, the latter being | ||
100% usage. | ||
=head1 METHODS | ||
=head2 new() | ||
$cpu = Proc::CPUUsage->new() | ||
Creates a new L<Proc::CPUUsage|Proc::CPUUsage> object with the current values for CPU usage. | ||
=head2 usage() | ||
$usage = $cpu->usage() | ||
Returns the CPU usage since the last call to L</"new()"> or L</"usage()">. | ||
The value returned is greater than 0 and lower or equal to 1. | ||
=head1 SEE ALSO | ||
L<AnyEvent::Monitor::CPU|AnyEvent::Monitor::CPU> for a more practical use for this module. | ||
=head1 AUTHOR | ||
Pedro Melo, C<< <melo at cpan.org> >> | ||
=head1 COPYRIGHT & LICENSE | ||
Copyright 2009 Pedro Melo. | ||
This program is free software; you can redistribute it and/or modify it | ||
under the same terms as Perl itself. | ||
=cut |
Oops, something went wrong.