285 lines
8.7 KiB
HTML
285 lines
8.7 KiB
HTML
<html>
|
|
<!--
|
|
copyright : (C) 2003-2004 Bernhard Wymann
|
|
email : berniw@bluewin.ch
|
|
version : $Id$
|
|
|
|
Permission is granted to copy, distribute and/or modify this document
|
|
under the terms of the GNU Free Documentation License, Version 1.2
|
|
or any later version published by the Free Software Foundation;
|
|
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
|
|
Texts. A copy of the license is included in the section entitled "GNU
|
|
Free Documentation License".
|
|
|
|
-->
|
|
<head>
|
|
<title>finishing the pit stop implementation</title>
|
|
<link rel="stylesheet" type="text/css" href="../../../css/format.css"/>
|
|
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"/>
|
|
<meta name="description" content="finishing the pit stop implementation"/>
|
|
<meta name="author" content="Bernhard Wymann"/>
|
|
<meta name="keywords" content="torcs, berniw, bernhard wymann, pit, pit stop"/>
|
|
<script src="../../../js/utilities.js" type="text/javascript"></script>
|
|
</head>
|
|
|
|
<body bgcolor="#ffffff">
|
|
<table class="maincontent">
|
|
<tr>
|
|
<td class="maincontent">
|
|
|
|
<h1>8.7 Put it All Together</h1>
|
|
|
|
<h3>Introduction</h3>
|
|
|
|
<p>
|
|
In this section we put all components we have built together. We have to
|
|
instantiate the pit class, integrate the pit callback and to compute
|
|
the target point with taking into account the pit offset.
|
|
</p>
|
|
|
|
<h3>Changes in driver.h</h3>
|
|
|
|
<p>
|
|
We include pit.h and add a prototype of the pit class.
|
|
</p>
|
|
|
|
<p><pre class="lcolor">#include "pit.h"</pre></p>
|
|
<p><pre class="lcolor">class Pit;</pre></p>
|
|
|
|
<p>
|
|
To remember our pit instance we need a variable. We also compute and remember the
|
|
current speed square, because we need it in several places.
|
|
</p>
|
|
|
|
<p><pre class="lcolor"> Pit *pit;
|
|
float currentspeedsqr;</pre></p>
|
|
|
|
<h3>Integration in driver.cpp</h3>
|
|
|
|
<h4>Creation and Destruction of the Pit Object</h4>
|
|
|
|
<p>
|
|
Add the release of our pit object into the destructor Driver::~Driver().
|
|
</p>
|
|
|
|
<p><pre class="lcolor"> delete pit;</pre></p>
|
|
|
|
<p>
|
|
Add the creation of the pit object into Driver::newRace(tCarElt* car, tSituation *s).
|
|
</p>
|
|
<p><pre class="lcolor"> /* create the pit object */
|
|
pit = new Pit(s, this);</pre></p>
|
|
|
|
|
|
<h4>Changes in Driver::drive(tSituation *s)</h4>
|
|
|
|
<p>
|
|
Swap the following two statements, because the initialization to
|
|
zero will overwrite the result of the pit update if it sets the pit race command.
|
|
Change in Driver::drive(tSituation *s)
|
|
</p>
|
|
|
|
<p><pre class="lbcolor"> update(s);
|
|
memset(&car->ctrl, 0, sizeof(tCarCtrl));</pre></p>
|
|
|
|
<p>
|
|
to
|
|
</p>
|
|
|
|
<p><pre class="lcolor"> memset(&car->ctrl, 0, sizeof(tCarCtrl));
|
|
update(s);</pre></p>
|
|
|
|
<p>
|
|
Change the brake value computation such that it takes into account the pit
|
|
brake filter. Change
|
|
</p>
|
|
|
|
<p><pre class="lbcolor"> car->ctrl.brakeCmd = filterABS(filterBColl(getBrake()));</pre></p>
|
|
|
|
<p>
|
|
to
|
|
</p>
|
|
|
|
<p><pre class="lcolor"> car->ctrl.brakeCmd = filterABS(filterBColl(filterBPit(getBrake())));</pre></p>
|
|
|
|
|
|
<h4>The Pit Callback</h4>
|
|
|
|
<p>
|
|
Now we integrate the pit getRepair and getFuel methods into the pit callback. We
|
|
set pitstop to false. Now it should be finally clear how a pit stop works. Our
|
|
car stops in the pit and if it is slow and near enough to the pit middle and
|
|
we request a pit stop, TORCS calls this callback function (remember chapter 2
|
|
where you registered it). We tell TORCS our wishes and set pitstop to false.
|
|
TORCS holds our car captured during the repair and refueling time, so we can't
|
|
drive away. After TORCS releases our car the drive function is called as usual
|
|
and we leave the pit. Replace
|
|
</p>
|
|
|
|
<p><pre class="lbcolor">/* Set pitstop commands. */
|
|
int Driver::pitCommand(tSituation *s)
|
|
{
|
|
return ROB_PIT_IM; /* return immediately */
|
|
}</pre></p>
|
|
|
|
<p>
|
|
with
|
|
</p>
|
|
|
|
<p><pre class="lcolor">/* Set pitstop commands */
|
|
int Driver::pitCommand(tSituation *s)
|
|
{
|
|
car->_pitRepair = pit->getRepair();
|
|
car->_pitFuel = pit->getFuel();
|
|
pit->setPitstop(false);
|
|
return ROB_PIT_IM; /* return immediately */
|
|
}</pre></p>
|
|
|
|
<h4>Change the Target Point Computation</h4>
|
|
|
|
<p>
|
|
Now we have to modify the getTargetPoint method. That you know where to insert
|
|
the code the unchanged code is in grey.
|
|
</p>
|
|
|
|
<p><pre class="lbcolor">/* compute target point for steering */
|
|
v2d Driver::getTargetPoint()
|
|
{
|
|
tTrackSeg *seg = car->_trkPos.seg;
|
|
float lookahead = LOOKAHEAD_CONST + car->_speed_x*LOOKAHEAD_FACTOR;
|
|
float length = getDistToSegEnd();
|
|
float offset = getOvertakeOffset();</pre></p>
|
|
|
|
<p>
|
|
If we are on the pit trajectory we switch to another computation of the
|
|
lookahead value. If we are in the speed limit range we even take a shorter
|
|
lookahead value. You could implement this also with one good formula.
|
|
</p>
|
|
|
|
|
|
<p><pre class="lcolor">
|
|
if (pit->getInPit()) {
|
|
if (currentspeedsqr > pit->getSpeedlimitSqr()) {
|
|
lookahead = PIT_LOOKAHEAD + car->_speed_x*LOOKAHEAD_FACTOR;
|
|
} else {
|
|
lookahead = PIT_LOOKAHEAD;
|
|
}
|
|
}</pre></p>
|
|
|
|
<p><pre class="lbcolor"> while (length < lookahead) {
|
|
seg = seg->next;
|
|
length += seg->length;
|
|
}
|
|
|
|
length = lookahead - length + seg->length;</pre></p>
|
|
|
|
<p>
|
|
We have to pass the distance to the start line of the target point to
|
|
getPitOffset, so we compute that first. After that we call the computation of
|
|
the pit offset.
|
|
</p>
|
|
|
|
<p><pre class="lcolor"> float fromstart = seg->lgfromstart;
|
|
fromstart += length;
|
|
offset = pit->getPitOffset(offset, fromstart);</pre></p>
|
|
|
|
<p><pre class="lbcolor"> v2d s;
|
|
s.x = (seg->vertex[TR_SL].x + seg->vertex[TR_SR].x)/2.0;
|
|
s.y = (seg->vertex[TR_SL].y + seg->vertex[TR_SR].y)/2.0;</pre></p>
|
|
|
|
<h4>Change the Update</h4>
|
|
|
|
<p>
|
|
The second last thing left is to update currentspeedsqr and to call the pit
|
|
update
|
|
method. Put this code at the end of Driver::update(tSituation *s).
|
|
</p>
|
|
|
|
<p><pre class="lcolor"> currentspeedsqr = car->_speed_x*car->_speed_x;
|
|
pit->update();</pre></p>
|
|
|
|
|
|
<h4>Change the Track Filter</h4>
|
|
|
|
<p>
|
|
Finally we need to modify Driver::filterTrk(float accel) that it does allow
|
|
accelerator commands in the pits. Change
|
|
</p>
|
|
|
|
<p><pre class="lbcolor"> if (car->_speed_x < MAX_UNSTUCK_SPEED) return accel;</pre></p>
|
|
|
|
<p>
|
|
to
|
|
</p>
|
|
|
|
<p><pre class="lcolor"> if (car->_speed_x < MAX_UNSTUCK_SPEED ||
|
|
pit->getInPit()) return accel;</pre></p>
|
|
|
|
<h3>Test Drive</h3>
|
|
|
|
<p>
|
|
Now everything should compile and work fine. To test the pit stops you can
|
|
insert the following line in the drive function to make the car stop on every lap.
|
|
If it works you can get now your cold juice out of the fridge... Cheers;-)
|
|
</p>
|
|
|
|
<p><pre class="lcolor"> pit->setPitstop(true);</pre></p>
|
|
|
|
<h3>Final Remarks</h3>
|
|
|
|
<p>
|
|
That finally was it, you got your TORCS driver license, congratulations.
|
|
I ask myself if
|
|
anybody will read till here, so in case you did, please let me know and tell
|
|
me your impressions. The reason for me to write this tutorial was to make it
|
|
easier for other people to build a robot and to understand the problem better.
|
|
I tried to separate the different functionality of the robot into filters
|
|
and classes, the goal was to keep them as independent as possible. In fact the
|
|
structure is much better than on my berniw robot, but I'm still not really
|
|
happy with it. Have fun and contribute to TORCS.<br/>
|
|
</br>
|
|
Bye, berniw.
|
|
</p>
|
|
|
|
<h3>Downloads</h3>
|
|
<p>
|
|
In case you got lost, you can <a href="../download/bt87.tar.gz">download</a> my robot for TORCS 1.2.0 or later.
|
|
</p>
|
|
|
|
<h3>Feedback</h3>
|
|
<p>
|
|
<a href="mailto:berni4you@gmx.ch">Let me know</a>
|
|
if you read this chapter and your thoughts about it. Please
|
|
<a href="mailto:berni4you@gmx.ch">send me</a>
|
|
also spelling, grammar, math and code corrections. Thank you for the feedback.
|
|
</p>
|
|
|
|
|
|
<h3>Summary</h3>
|
|
<ul style="list-style-type:disk; color:black;">
|
|
<li>You have understood a full featured robot and you are ready to improve it
|
|
or build your own from scratch.</li>
|
|
</ul>
|
|
<br/>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<table class="navigation_foot">
|
|
<tr>
|
|
<td class="navigation_foot">
|
|
<a href="./brake.html">
|
|
<p style="text-align:left;">Back</p>
|
|
</a>
|
|
</td>
|
|
<td class="navigation_foot">
|
|
<a href="javascript:changetwoframes('../navigation/navigation.html','navigation','../robot.html','content')">
|
|
<p style="text-align:right;">Up</p>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
</body>
|
|
</html>
|