]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/simplecontroller.cpp
e7d9352ca048bd8377570476662860d1662d5fd3
[r2c2.git] / source / libr2c2 / simplecontroller.cpp
1 /* $Id$
2
3 This file is part of R²C²
4 Copyright © 2010  Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
6 */
7
8 #include <msp/core/except.h>
9 #include <msp/time/units.h>
10 #include "simplecontroller.h"
11
12 using namespace std;
13 using namespace Msp;
14
15 namespace R2C2 {
16
17 SimpleController::SimpleController():
18         target_speed(Control::continuous("speed", 0, 1000)),
19         reverse(Control::binary("reverse")),
20         accel(0.07),
21         speed(0)
22 {
23         target_speed.set(0);
24 }
25
26 const char *SimpleController::enumerate_controls(unsigned index) const
27 {
28         if(index==0)
29                 return target_speed.name.c_str();
30         else if(index==1)
31                 return reverse.name.c_str();
32         else
33                 return 0;
34 }
35
36 void SimpleController::set_control(const string &name, float v)
37 {
38         if(name==target_speed.name)
39         {
40                 target_speed.set(v);
41                 signal_control_changed.emit(target_speed);
42         }
43         else if(name==reverse.name)
44         {
45                 if(target_speed.value || speed)
46                         throw InvalidState("Must be stopped to change reverse");
47                 reverse.set(v);
48                 signal_control_changed.emit(reverse);
49         }
50 }
51
52 const Controller::Control &SimpleController::get_control(const string &name) const
53 {
54         if(name==target_speed.name)
55                 return target_speed;
56         else if(name==reverse.name)
57                 return reverse;
58         else
59                 throw KeyError("Unknown control", name);
60 }
61
62 float SimpleController::get_braking_distance() const
63 {
64         return speed*speed/(2*accel);
65 }
66
67 void SimpleController::tick(const Time::TimeDelta &dt)
68 {
69         float secs = dt/Time::sec;
70         if(speed<target_speed.value)
71         {
72                 speed += secs*accel;
73                 if(speed>target_speed.value)
74                         speed = target_speed.value;
75         }
76         else if(speed>target_speed.value)
77         {
78                 speed -= secs*accel;
79                 if(speed<target_speed.value)
80                         speed = target_speed.value;
81         }
82 }
83
84 } // namespace R2C2