--- /dev/null
+/* $Id$
+
+This file is part of R²C²
+Copyright © 2010 Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#include <msp/core/except.h>
+#include <msp/time/units.h>
+#include "simplecontroller.h"
+
+using namespace std;
+using namespace Msp;
+
+namespace R2C2 {
+
+SimpleController::SimpleController():
+ target_speed(Control::continuous("speed", 0, 1000)),
+ reverse(Control::binary("reverse")),
+ accel(0.07),
+ speed(0)
+{
+ target_speed.set(0);
+}
+
+void SimpleController::set_control(const string &name, float v)
+{
+ if(name=="speed")
+ {
+ target_speed.set(v);
+ signal_control_changed.emit(target_speed);
+ }
+ else if(name=="reverse")
+ {
+ if(target_speed.value || speed)
+ throw InvalidState("Must be stopped to change reverse");
+ reverse.set(v);
+ signal_control_changed.emit(reverse);
+ }
+}
+
+const Controller::Control &SimpleController::get_control(const string &name) const
+{
+ if(name=="speed")
+ return target_speed;
+ else if(name=="reverse")
+ return reverse;
+ else
+ throw KeyError("Unknown control", name);
+}
+
+float SimpleController::get_braking_distance() const
+{
+ return speed*speed/(2*accel);
+}
+
+void SimpleController::tick(const Time::TimeDelta &dt)
+{
+ float secs = dt/Time::sec;
+ if(speed<target_speed.value)
+ {
+ speed += secs*accel;
+ if(speed>target_speed.value)
+ speed = target_speed.value;
+ }
+ else if(speed>target_speed.value)
+ {
+ speed -= secs*accel;
+ if(speed<target_speed.value)
+ speed = target_speed.value;
+ }
+}
+
+} // namespace R2C2