summaryrefslogtreecommitdiffstats
path: root/qtbotsim/robot.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qtbotsim/robot.cpp')
-rw-r--r--qtbotsim/robot.cpp212
1 files changed, 212 insertions, 0 deletions
diff --git a/qtbotsim/robot.cpp b/qtbotsim/robot.cpp
new file mode 100644
index 0000000..8265a3b
--- /dev/null
+++ b/qtbotsim/robot.cpp
@@ -0,0 +1,212 @@
+/*
+ * In the original BSD license, both occurrences of the phrase "COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS" in the disclaimer read "REGENTS AND CONTRIBUTORS".
+ *
+ * Here is the license template:
+ *
+ * Copyright (c) 2011, Johan Thelin <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of Johan Thelin nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "robot.h"
+
+#include <QPainterPath>
+#include <math.h>
+
+Robot::Robot(QObject *parent)
+ : QObject(parent)
+{
+ // All is reset in the reset method called first
+}
+
+void Robot::step(QPixmap *pixmap)
+{
+ QPointF start = position();
+ setPosition(position()+movementChange());
+ QPointF end = position();
+ setDirection(direction()+directionChange());
+
+ if (m_penActive)
+ {
+ QPainter p(pixmap);
+ p.setRenderHint(QPainter::Antialiasing);
+ p.setPen(Qt::red);
+ p.drawLine(start, end);
+ }
+
+ updateSensors(*pixmap);
+}
+
+void Robot::drawOverlay(QPainter &painter)
+{
+ QPainterPath path;
+
+ path.addRect(QRectF(-QPointF(10, 20), QSizeF(20, 40)));
+ path.addEllipse(QPointF(0, 15), 2, 2);
+
+ painter.setPen(Qt::black);
+ painter.setBrush(Qt::lightGray);
+
+ painter.translate(position());
+ painter.rotate(direction());
+
+ painter.drawPath(path);
+}
+
+bool Robot::brightForward() const
+{
+ return m_brightForward;
+}
+
+bool Robot::penActive() const
+{
+ return m_penActive;
+}
+
+qreal Robot::leftEngineSpeed() const
+{
+ return m_leftEngineSpeed;
+}
+
+qreal Robot::rightEngineSpeed() const
+{
+ return m_rightEngineSpeed;
+}
+
+void Robot::reset(const QPixmap &pixmap)
+{
+ setPenActive(true);
+ setLeftEngineSpeed(0);
+ setRightEngineSpeed(0);
+ setDirection(270);
+ setPosition(QPointF(pixmap.width()/2, pixmap.height()/2));
+ updateSensors(pixmap);
+}
+
+void Robot::setPenActive(bool pa)
+{
+ if (pa != m_penActive)
+ {
+ m_penActive = pa;
+ emit penActiveChanged(m_penActive);
+ }
+}
+
+void Robot::setLeftEngineSpeed(qreal s)
+{
+ s = qBound(-1.0, s, 1.0);
+
+ if (s != m_leftEngineSpeed)
+ {
+ m_leftEngineSpeed = s;
+ emit leftEngineSpeedChanged(m_leftEngineSpeed);
+ }
+}
+
+void Robot::setRightEngineSpeed(qreal s)
+{
+ s = qBound(-1.0, s, 1.0);
+
+ if (s != m_rightEngineSpeed)
+ {
+ m_rightEngineSpeed = s;
+ emit rightEngineSpeedChanged(m_rightEngineSpeed);
+ }
+}
+
+QPointF Robot::position() const
+{
+ return m_position;
+}
+
+void Robot::setPosition(const QPointF &p)
+{
+ m_position = p;
+}
+
+qreal Robot::direction() const
+{
+ return m_direction;
+}
+
+void Robot::setDirection(qreal d)
+{
+ while (d>360.0)
+ d -= 360.0;
+
+ m_direction = d;
+}
+
+void Robot::setBrightForward(bool value)
+{
+ if (value != m_brightForward)
+ {
+ m_brightForward = value;
+ emit brightForwardChanged(m_brightForward);
+ }
+}
+
+void Robot::updateSensors(const QPixmap &paper)
+{
+ QTransform t;
+ t.rotate(direction());
+ QPointF sensorPos = position() + t.map(QPointF(0, 15));
+
+ setBrightForward(qGray(paper.toImage().pixel(sensorPos.toPoint())) > 20);
+}
+
+QPointF Robot::movementChange() const
+{
+ QTransform t;
+ t.rotate(direction()+directionChange());
+
+ return t.map(QPointF(0, (leftEngineSpeed() + rightEngineSpeed())/2));
+}
+
+qreal Robot::directionChange() const
+{
+ /*
+
+ <----+----> lwS
+ | .
+ | .
+ | .
+ | .
+ |a x----------------------
+ |-. .... ) a
+ | . ....
+ |. ....
+ |. ....
+ <----+----> rwR
+
+
+ */
+
+ qreal tangens = (leftEngineSpeed()-rightEngineSpeed())/20.0;
+ qreal angle = atan(tangens);
+
+ return angle*180.0/M_PI;
+}