TractortankObject simulates the two motors of a tank steered robot base. It takes four analog inputs. Two represent the inputs to the motors. Two represent the resulting motion.
TractortankObject.tcl will typically be sourced in TheRobot.tcl. The declaration for ::Tractortank::new will then also be created in TheRobot.tcl.
|
The black arrows represent the input power to the motors. The red arrows represent the resulting motion, which may lag due to inertia. That is what is shown in this example. Each of these four numbers must be in the range -1.0 to 1.0. The top line of text is the comment field. The middle line is the leftpwm and rightpwm values. The bottom line is the distance traveled by that wheel. The tractor motors are represented by arrows and by the numbers below them. The value 127 is zero power. When a motor channel receives a number greater than 127, up to 255, the arrow extends up. When a motor channel receives a number less than 127, down to 0, the arrow extends down. |
There are two proc[edures] in TractortankObject.tcl. The first few lines of each proc lists the parameters required.
proc new { {TractorName} {NameOnCanv} {Xs} {Ys} {offset} \
{leftpwm} {rightpwm} {leftinpower} {rightinpower} \
{leftoutpower} {rightoutpower} \
{leftdist} {rightdist} {leftmaxspeed} {rightmaxspeed} \
{simseconds} {BackColor} {Comment} } \
{
  # TractorName = Unique name for the Tractor.
  # NameOnCanv = Graphic path to the tractor object.
  # Xs and Ys = Screen size of Tractor.
  # offset = Screen 1/2 distance between tractor halves.
  # leftpwm, rightpwm = Variable containing the left/right PWM. Displays text.
  # leftinpower, rightinpower = Left/Right side input power expr
  # (-1 to 1). Display black line.
  # leftoutpower, rightoutpower = Left/Right side output power expr
  # (-1 to 1). Display red line. If this param is
  # specified as {}, the inpower values will be used.
  # leftdist, rightdist = Variable to store distance traveled on that side.
  # leftmaxspeed, rightmaxspeed = Maximum speed in distance units
  # per second. (Probably inches per second.)
  # simseconds = Variable containing simulation time in seconds.
  # BackColor = Background color the tractor sits on.
  # Comment = Text to be displayed on the tractor image.
The parameters TractorName and NameOnCanv are constants. Xs and Ys determine the size of the tractor image on the screen. Offset is the screen distance between the two motors. BackColor is the background color. Comment is displayed unchanged.
The current values of leftpwm and rightpwm are displayed on the middle line of text in the GUI. That is all that is done with them. They may be expressions.
The current values of leftinpower and rightinpower are displayed as the height of the black lines on the GUI. They may be expressions. Their value must be between -1.0 and 1.0.
The current values of leftoutpower and rightoutpower are displayed as the height of the red lines on the GUI. They may be expressions. Their value must be between -1.0 and 1.0. In addition these numbers are used to calculate distance traveled.
If leftoutpower and rightoutpower are each specified as {} leftinpower and rightinpower respecively will be used in their place for calculating line height and distance traveled. In this case only the red lines will be displayed.
The parameters leftdist and rightdist need to specify the names of variables where the cumulative distance can be stored.
leftmaxspeed and rightmaxspeed specify the maximum speed of the robot when outpower is 1.0.
The total instantaneous simulation time must be provided in simseconds. This is used to determine distance traveled.
proc update { {TractorName} }\
{
variable $TractorName
::Tractortank::update needs to be called, typically by using
::Notify::Subscribe Cycle
We can put a tractor against the top side of a frame using code like this:
source {TractortankObject.tcl}
toplevel .robot; wm group .robot .
::Tractortank::new tractor .robot.tractor 120 256 20 \
{$::pwm16} {$::pwm15} \
{[ifibyte2fract $::pwm16 -1]} {[ifibyte2fract $::pwm15 1]} \
{[ifibyte2fract $::pwm16 -1]} {[ifibyte2fract $::pwm15 1]} \
{[::Powertransfer::update {rightpower}]} \
{::leftdist} {::rightdist} {5} {5} \
{$::simseconds} "#7f8f7f" "pwm16 pwm15"
pack .robot.tractor -side top
The declaration above is in TheRobot.tcl. The double colons in front of each variable name makes them operate at the root namespace of the Tcl program. In this example, the right side motor runs forward.
::Tractortank::update tractor
The update code above is passed to Notify using
::Notify::Subscribe Cycle ::Tractortank::update tractorEach time it is called, the Tractor image is updated based on the values of the root scope variables $::pwm16 and $::pwm15.