PowertransferObject provides a convenient way to represent and model input power to output response. Internally it only simulates inertia. However, because of the way it interprets its input power, it provides a more succinct way to specify other transformations such as coupled output. This will be shown below.
PowertransferObject.tcl will typically be sourced in TheRobot.tcl. The declaration for ::Powertransfer::new will then also be created in TheRobot.tcl.
Powertransfer has no GUI view. Instead its effects are seen in other GUIs such as Tractortank.
There are two proc[edures] in PowertransferObject.tcl. The first few lines of each proc lists the parameters required.
proc new { {PowertransferName} {powerequation} {accel} {decel} } \
{
  # PowertransferName = Unique name for the Powertransfer object.
  # powerequation = Input equation before inertia.
  # accel/decel = Time required to start/stop.
Creates a new Powertransfer Object.
proc update { {PowertransferName} } \
{
Typically ::Powertransfer:: will be managed by Tractortank. See the example below.
A tank style tractor will generally use one ::Powertransfer:: object per side. Lets consider what TheRobot.tcl looks like.
source {PowertransferObject.tcl}
::Powertransfer::new {leftpower} {[ifibyte2fract $::pwm16 -1]} 1 2
::Powertransfer::new {rightpower} {[ifibyte2fract $::pwm15 1]} 1 2
::Tractortank::new tractor1 $labelname 120 256 20 \
{$::pwm16} {$::pwm15} \
{[ifibyte2fract $::pwm16 -1]} {[ifibyte2fract $::pwm15 1]} \
{[::Powertransfer::update {leftpower}]} \
{[::Powertransfer::update {rightpower}]} \
{::leftdist} {::rightdist} {5} {5} \
{$::simseconds} "#7f8f7f" "pwm16 pwm15"
After sourcing the Powertransfer object definition, we declare two instances, leftpower and rightpower. The procedure ifibyte2fract (in simfuncs.html ) converts that funky 0 to 255 number system to a range of -1.0 to 1.0. That latter range is what Tractortank requires.
Then ::Powertransfer::update {leftpower} is passed to the leftoutpower parameter of ::Tractortank::new. Because of the [] around ::Powertransfer::update, it will be called as a function whenever ::Tractortank:: references that parameter. The right side is handled similarly.
The last two parameters specify that acceleration takes 1 second and decelleration takes 2.
This is a simple example. The outputs to the tractor motion tracks the input smoothly except for inertia. However Powertransfer is capable of more complex interactions.
In 4 wheeled tank driven tractors there is substantial interaction between the two sides. This is because the friction of driving on carpet makes it very difficult to steer. It is as tho power applied to the left side "leaks" over to the right side. There are mechanical ways to avoid this problem, but here I want to concentrate on modeling the awkward behavior so that our simulation doesn't ignore it.
By changing the declarations as shown here we can model this.
::Powertransfer::new {leftpower} \
{0.7*[ifibyte2fract $::pwm16 -1]+0.3*[ifibyte2fract $::pwm15 1]} \
1 2
::Powertransfer::new {rightpower} \
{0.3*[ifibyte2fract $::pwm16 -1]+0.7*[ifibyte2fract $::pwm15 1]} \
1 2
Now the left side receives power from both the left and right side motors. Seems odd, but that is really how these robots drive. In this case I have provided a 70%/30% mix. This is not an unreasonable guess for a four wheeled robot. By the way, make sure your mix always adds up to 100%.
But there are other odd components we may want to model. The motor controller from IFI, the Victor884, does not put out quite what you ask it to. Instead it has a dead zone close to its middle of range. It can be important that you model this since some control algorithms such as PID (Proportional, Integral, Derivative) can be made unusable by the discontinuous behaviour of the Victor884. Let's add the Victor to the simulation.
Since the Victor884 works on ifibytes rather than the range -1.0 to 1.0, we need to call it before ifibyte2fract. Adding that to the previous example we get:
::Powertransfer::new {leftpower} \
{0.7*[ifibyte2fract [Victor884 137 117 $::pwm16] -1] \
+0.3*[ifibyte2fract [Victor884 137 117 $::pwm15] 1]} \
0 0
::Powertransfer::new {rightpower} \
{0.3*[ifibyte2fract [Victor884 137 117 $::pwm16] -1] \
+0.7*[ifibyte2fract [Victor884 137 117 $::pwm15] 1]} \
0 0
In this example I have made the inertia zero. That is good for seeing the results of the non-linearity. But once it is working the way you expect you probably want to put inertia back in.