File: standaloneServerDemo.cpp

package info (click to toggle)
libaria 2.8.0%2Brepack-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 13,628 kB
  • ctags: 16,574
  • sloc: cpp: 135,490; makefile: 925; python: 597; java: 570; ansic: 182
file content (191 lines) | stat: -rw-r--r-- 5,547 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#include "Aria.h"
#include "ArNetworking.h"

class InputHandler
{
public:
  InputHandler(ArServerBase *server, ArRobot *robot);
  virtual ~InputHandler(void);
  void setVel(ArServerClient *client, ArNetPacket *packet);
  void deltaVel(ArServerClient *client, ArNetPacket *packet);
  void deltaHeading(ArServerClient *client, ArNetPacket *packet);
protected:
  ArActionInput myActionInput;
  ArRobot *myRobot;
  ArServerBase *myServer;
  ArFunctor2C<InputHandler, ArServerClient *, ArNetPacket *> mySetVelCB;
  ArFunctor2C<InputHandler, ArServerClient *, ArNetPacket *> myDeltaVelCB;
  ArFunctor2C<InputHandler, ArServerClient *, ArNetPacket *> myDeltaHeadingCB;
};

InputHandler::InputHandler(ArServerBase *server, ArRobot *robot) :
  mySetVelCB(this, &InputHandler::setVel),
  myDeltaVelCB(this, &InputHandler::deltaVel),
  myDeltaHeadingCB(this, &InputHandler::deltaHeading)
{
  myRobot = robot;
  myServer = server;
  myRobot->addAction(&myActionInput, 50);
  myServer->addData("setVel", "sets the velocity of the robot", &mySetVelCB,
		    "double: vel", "none");
  myServer->addData("deltaVel", "changes the velocity of the robot", 
		    &myDeltaVelCB, "double: deltaVel", "none");
  myServer->addData("deltaHeading", "changes the heading of the robot", 
		    &myDeltaHeadingCB, "double: deltaHeading", "none");
}

InputHandler::~InputHandler(void)
{
  myRobot->remAction(&myActionInput);
  /*myServer->remData("setVel");
  myServer->remData("deltaVel");
  myServer->remData("deltaHeading");*/
}

void InputHandler::setVel(ArServerClient *client, ArNetPacket *packet)
{
  double vel = packet->bufToDouble();
  //printf("Vel %g\n", vel);
  myActionInput.setVel(vel);
}
 
void InputHandler::deltaVel(ArServerClient *client, ArNetPacket *packet)
{
  double delta = packet->bufToDouble();
  //printf("DeltaVel %g\n", delta);
  //myActionInput.deltaVel(delta); // deltaVel has been removed from ArActionInput 
  myActionInput.setVel(myRobot->getVel() + delta);
}
 
void InputHandler::deltaHeading(ArServerClient *client, ArNetPacket *packet)
{
  double delta = packet->bufToDouble();
  //printf("DeltaHeading %g\n", delta);
  myActionInput.deltaHeadingFromCurrent(delta);
}

class OutputHandler
{
public:
  OutputHandler(ArServerBase *server, ArRobot *robot);
  virtual ~OutputHandler(void);
  void buildOutput(void);
  void output(ArServerClient *client, ArNetPacket *packet);

protected:
  ArServerBase *myServer;
  ArRobot *myRobot;
  ArMutex myPacketMutex;
  ArNetPacket myBuiltPacket;
  ArNetPacket mySendingPacket;
  ArFunctor2C<OutputHandler, ArServerClient *, ArNetPacket *> myOutputCB;
  ArFunctorC<OutputHandler> myTaskCB;
};

OutputHandler::OutputHandler(ArServerBase *server, ArRobot *robot) :
  myOutputCB(this, &OutputHandler::output),
  myTaskCB(this, &OutputHandler::buildOutput)
{
  myServer = server;
  myRobot = robot;
  myServer->addData("output", "gives the status of the robot", &myOutputCB,
		    "none", "byte4: x, byte4: y, byte2: th*10, byte2: vel, byte2: rotvel, byte2: battery*10");
  myRobot->addUserTask("output", 50, &myTaskCB);
}

OutputHandler::~OutputHandler(void)
{

}

void OutputHandler::buildOutput(void)
{
  myPacketMutex.lock();
  myBuiltPacket.empty();
  myBuiltPacket.byte4ToBuf(ArMath::roundInt(myRobot->getX()));
  myBuiltPacket.byte4ToBuf(ArMath::roundInt(myRobot->getY()));
  myBuiltPacket.byte2ToBuf(ArMath::roundInt(myRobot->getTh()));
  myBuiltPacket.byte2ToBuf(ArMath::roundInt(myRobot->getVel()));
  myBuiltPacket.byte2ToBuf(ArMath::roundInt(myRobot->getRotVel()));
  myBuiltPacket.byte2ToBuf(ArMath::roundInt(
	  myRobot->getBatteryVoltage() * 10));
  myPacketMutex.unlock();
}

void OutputHandler::output(ArServerClient *client, ArNetPacket *packet)
{
  myPacketMutex.lock();
  mySendingPacket.duplicatePacket(&myBuiltPacket);
  myPacketMutex.unlock();
  client->sendPacketTcp(&mySendingPacket);
}

int main(int argc, char **argv)
{
  Aria::init();
  ArServerBase server;
  // the serial connection (robot)
  ArSerialConnection serConn;
  // tcp connection (sim)
  ArTcpConnection tcpConn;
  // robot
  ArRobot robot;

  // first open the server up
  if (!server.open(7272))
  {
    printf("Could not open server port\n");
    exit(1);
  }
  // attach stuff to the server
  InputHandler inputHandler(&server, &robot);
  OutputHandler outputHandler(&server, &robot);
  // now let it spin off in its own thread
  server.runAsync();

  
  tcpConn.setPort();
  // see if we can get to the simulator  (true is success)
  if (tcpConn.openSimple())
  {
    // we could get to the sim, so set the robots device connection to the sim
    printf("Connecting to simulator through tcp.\n");
    robot.setDeviceConnection(&tcpConn);
  }
  else
  {
    // we couldn't get to the sim, so set the port on the serial
    // connection and then set the serial connection as the robots
    // device

    // modify the next line if you're not using the first serial port
    // to talk to your robot
    serConn.setPort();
    printf(
      "Could not connect to simulator, connecting to robot through serial.\n");
    robot.setDeviceConnection(&serConn);
  }

  // try to connect, if we fail exit
  if (!robot.blockingConnect())
  {
    printf("Could not connect to robot... exiting\n");
    Aria::shutdown();
    return 1;
  }
  // enable the motors, disable amigobot sounds
  robot.comInt(ArCommands::ENABLE, 1);
  robot.comInt(ArCommands::BUMPSTALL, 0);
  
  // run the robot, true here so that the run will exit if connection lost
  robot.run(true);
  
  // now exit
  Aria::shutdown();



  return 0;
}