]> git.tdb.fi Git - r2c2.git/blob - source/serial/serial.cpp
New approach for displaying track state
[r2c2.git] / source / serial / serial.cpp
1 #include <msp/net/resolve.h>
2 #include "serial.h"
3
4 #include <msp/io/print.h>
5
6 using namespace std;
7 using namespace Msp;
8 using namespace R2C2;
9         
10 Serial::Serial(int, char **argv):
11         client(catalogue),
12         serial_port(argv[2]),
13         train(0),
14         reverse(false),
15         rx_fill(0)
16 {
17         DataFile::load(catalogue, "locos.dat");
18
19         client.use_event_dispatcher(event_disp);
20         client.signal_train_added.connect(sigc::mem_fun(this, &Serial::train_added));
21         client.signal_error.connect(sigc::mem_fun(this, &Serial::error));
22
23         string addr_str = argv[1];
24         if(addr_str.find(':')==string::npos)
25                 addr_str += ":8315";
26         Net::SockAddr *addr = Net::resolve(addr_str);
27         client.connect(*addr);
28         delete addr;
29
30         serial_port.set_parameters("9600,8N1");
31         event_disp.add(serial_port);
32         serial_port.signal_data_available.connect(sigc::mem_fun(this, &Serial::data_available));
33 }
34
35 void Serial::tick()
36 {
37         event_disp.tick();
38 }
39
40 void Serial::train_added(NetTrain &t)
41 {
42         if(!train)
43                 set_train(&t);
44 }
45
46 void Serial::error(const string &e)
47 {
48         IO::print("%s\n", e);
49 }
50
51 void Serial::set_train(NetTrain *t)
52 {
53         train = t;
54         serial_port.write(format("A%02d", train->get_address()));
55 }
56
57 void Serial::next_train()
58 {
59         const map<unsigned, NetTrain *> &trains = client.get_trains();
60
61         map<unsigned, NetTrain *>::const_iterator i = trains.find(train->get_address());
62         ++i;
63         if(i==trains.end())
64                 i = trains.begin();
65
66         set_train(i->second);
67 }
68
69 void Serial::prev_train()
70 {
71         const map<unsigned, NetTrain *> &trains = client.get_trains();
72
73         map<unsigned, NetTrain *>::const_iterator i = trains.find(train->get_address());
74         if(i==trains.begin())
75                 i = trains.end();
76         --i;
77
78         set_train(i->second);
79 }
80
81 void Serial::data_available()
82 {
83         char c;
84         serial_port.read(&c, 1);
85         if(rx_fill==0)
86         {
87                 if(c=='S' || c=='H' || c=='L')
88                         rx_buf[rx_fill++] = c;
89                 else if(c=='R')
90                 {
91                         IO::print("Reverse\n");
92                         reverse = !reverse;
93                         train->set_control("speed", 0);
94                 }
95                 else if(c=='N')
96                         next_train();
97                 else if(c=='P')
98                         prev_train();
99         }
100         else
101         {
102                 rx_buf[rx_fill++] = c;
103                 if(rx_buf[0]=='H' && rx_fill==2)
104                 {
105                         train->set_function(rx_buf[1]-'0', true);
106                         IO::print("Func %d on\n", rx_buf[1]-'0');
107                         rx_fill = 0;
108                 }
109                 else if(rx_buf[0]=='L' && rx_fill==2)
110                 {
111                         train->set_function(rx_buf[1]-'0', false);
112                         IO::print("Func %d off\n", rx_buf[1]-'0');
113                         rx_fill = 0;
114                 }
115                 else if(rx_buf[0]=='S' && rx_fill==3)
116                 {
117                         // XXX The firmware is still coded for speed step based control
118                         float speed = ((rx_buf[1]-'0')*10+(rx_buf[2]-'0'))*10/3.6*catalogue.get_scale();
119                         IO::print("Set speed %g\n", speed);
120                         train->set_control("speed", speed);
121                         rx_fill = 0;
122                 }
123         }
124 }