[TeamTalk 38]: [575] TeamTalk: Made changes to support MakeLM in its new location as an olympus tool.
tk@edam.speech.cs.cmu.edu
tk at edam.speech.cs.cmu.edu
Fri Apr 6 16:09:41 EDT 2007
An HTML attachment was scrubbed...
URL: http://mailman.srv.cs.cmu.edu/pipermail/teamtalk-developers/attachments/20070406/30a0a1d5/attachment-0001.html
-------------- next part --------------
Modified: TeamTalk/Agents/PrimitiveComm/robot_packet2.cpp
===================================================================
--- TeamTalk/Agents/PrimitiveComm/robot_packet2.cpp 2007-04-05 20:17:36 UTC (rev 574)
+++ TeamTalk/Agents/PrimitiveComm/robot_packet2.cpp 2007-04-06 20:09:41 UTC (rev 575)
@@ -1,705 +1,705 @@
-#include "robot_packet2.h"
-#include "utils.h"
-#include "netutils.h"
-
-//these are for Msg::stamp
-#include <sys/types.h>
-#include <sys/timeb.h>
-
-#include <sstream>
-
-using namespace std;
-using namespace geometry;
-
-// MalformedPacketException *******************************************
-
-MalformedPacketException::MalformedPacketException(const string& context, const string& rep) throw() {
- ostringstream e;
- e << context << ": " << rep;
- error = e.str();
-}
-
-MalformedPacketException::~MalformedPacketException() throw() {}
-
-const char* MalformedPacketException::what() throw() {return error.c_str();}
-
-// TaskStatus *********************************************************
-
-const char* TaskStatus::map_[] =
- {"ABANDONED", "FAILED", "UNSENT", "UNACKED", "IN_PROGRESS", "SUCCEEDED"};
-
-TaskStatus::TaskStatus() : status_(TaskStatus::UNSENT) {}
-TaskStatus::TaskStatus(TaskStatus::Enum x) : status_(x) {}
-
-int TaskStatus::boeingStatus(TaskStatus x)
-{
- switch(x.status_) {
- case ABORTED: return Boeing::ABORTED;
- case FAILED: return Boeing::FAILED;
- case UNSENT:
- case UNACKED:
- case IN_PROGRESS: return Boeing::INPROGRESS;
- case SUCCEEDED: return Boeing::SUCCEEDED;
- default: error << "unknown status " << x;
- }
- return 0;
-}
-
-TaskStatus TaskStatus::statusOfBoeing(int x)
-{
- if(x == Boeing::ABORTED) return TaskStatus(ABORTED);
- if(x == Boeing::FAILED) return TaskStatus(FAILED);
- if(x >= Boeing::SUCCEEDED) return SUCCEEDED;
- return IN_PROGRESS;
-}
-
-TaskStatus TaskStatus::operator=(TaskStatus::Enum x) {
- status_ = x;
- return *this;
-}
-
-TaskStatus::operator const char *() const {return map_[status_];}
-
-bool TaskStatus::isInProgress() const {return status_ == IN_PROGRESS;}
-bool TaskStatus::isFailed() const {return status_ == FAILED;}
-bool TaskStatus::isAborted() const {return status_ == ABORTED;}
-bool TaskStatus::isSuccess() const {return status_ == SUCCEEDED;}
-
-// Msg ****************************************************************
-
-int Msg::taskIDCounter = 0;
-const int Msg::defaultPriority = 1;
-
-//normal instantiation
-Msg::Msg(string sender) : sender_(sender) {}
-//instantiation from Boeing packet
-Msg::Msg(string sender, double tstamp) : sender_(sender), tstamp_(tstamp) {}
-
-Msg::Msg(const Msg& m) : sender_(m.sender_), tstamp_(m.tstamp_) {}
-
-Msg::~Msg() {}
-
-Msg* Msg::interpretBoeingPacket(const string& m, const string& sender)
-{
- const Boeing::MsgHeader *h =
- reinterpret_cast<const Boeing::MsgHeader*>(m.c_str());
- double tstamp = h->tstamp;
- int type = h->type;
- //messages to robots
- if(type == Boeing::ROB_ACTION_ECHO || type == Boeing::CMD_ACTION) {
- debug("packet") << "got: CMD_ACTION or ROB_ACTION_ECHO" << endl;
- return MsgCmd::interpretBoeingPlayAction(
- reinterpret_cast<const Boeing::MsgCmdAction*>(m.c_str()), sender, tstamp);
- }
- if(type == Boeing::CMD_COVER) {
- warn("packet") << "unhandled type: CMD_COVER " << endl;
- return NULL;
- }
- if(type == Boeing::CMD_FOLLOW) {
- warn("packet") << "unhandled type: CMD_FOLLOW " << endl;
- return NULL;
- }
- if(type == Boeing::CMD_GOTO) {
- warn("packet") << "unhandled type: CMD_GOTO " << endl;
- return NULL;
- }
- if(type == Boeing::CMD_HALT) {
- warn("packet") << "unhandled type: CMD_HALT " << endl;
- return NULL;
- }
- if(type == Boeing::CMD_HOME) {
- warn("packet") << "unhandled type: CMD_HOME " << endl;
- return NULL;
- }
- if(type == Boeing::CMD_PAUSE) {
- warn("packet") << "unhandled type: CMD_PAUSE " << endl;
- return NULL;
- }
- if(type == Boeing::CMD_RESUME) {
- warn("packet") << "unhandled type: CMD_RESUME " << endl;
- return NULL;
- }
- if(type == Boeing::CMD_SETPOS) {
- warn("packet") << "unhandled type: CMD_SETPOS " << endl;
- return NULL;
- }
- if(type == Boeing::REQ_LOCATION) {
- debug("packet") << "got: REQ_LOCATION" << endl;
- return new MsgReqLocation(sender, tstamp);
- }
- if(type == Boeing::REQ_IMAGE) {
- debug("packet") << "got: REQ_IMAGE" << endl;
- return new MsgMapReq(sender, tstamp,
- reinterpret_cast<const Boeing::MsgMapReq*>(m.c_str())->invoice);
- }
- //messages from robots
- if(type == Boeing::ROB_LOCATION) {
- debug("packet") << "got ROB_LOCATION" << endl;
- const Boeing::MsgRobLocation* brl =
- reinterpret_cast<const Boeing::MsgRobLocation*>(m.c_str());
- return new MsgRobLocation(sender, brl->tstamp,
- geometry::Point<float>(brl->x, brl->y), brl->angle, (brl->moving != 0));
- }
- if(type == Boeing::ROB_ACK) {
- debug("packet") << "got: ROB_ACK" << endl;
- return new MsgRobAck(sender, tstamp,
- reinterpret_cast<const Boeing::MsgRobAck*>(m.c_str())->taskid);
- }
- if(type == Boeing::ROB_ACTION_ACK) {
- warn("packet") << "unhandled type: ROB_ACTION_ACK " << h->type << endl;
- debug("packet") << "got: ROB_ACTION_ACK" << endl;
- const Boeing::MsgActionAck* bp = reinterpret_cast<const Boeing::MsgActionAck*>(m.c_str());
- return new MsgRobActionAck(sender, tstamp, bp->taskid, (bp->status == Boeing::SUCCEEDED));
- }
- if(type == Boeing::ROB_DONE) {
- debug("packet") << "got: ROB_DONE" << endl;
- const Boeing::MsgRobDone* bp = reinterpret_cast<const Boeing::MsgRobDone*>(m.c_str());
- if(bp->status == Boeing::SUCCEEDED)
- return new MsgRobDone(sender, tstamp, bp->taskid, TaskStatus::SUCCEEDED);
- else if(bp->status == Boeing::FAILED)
- return new MsgRobDone(sender, tstamp, bp->taskid, TaskStatus::FAILED);
- else if(bp->status == Boeing::ABORTED)
- return new MsgRobDone(sender, tstamp, bp->taskid, TaskStatus::ABORTED);
- else {
- error << "couldn't get Boeing::ROB_DONE status" << endl;
- return NULL;
- }
- }
- if(type == Boeing::ROB_PLAY_HALT) {
- warn("packet") << "unhandled type: ROB_PLAY_HALT " << endl;
- return NULL;
- }
- if(type == Boeing::ROB_IMAGE) {
- debug("packet") << "got: ROB_IMAGE" << endl;
- const Boeing::MsgMap* bp = reinterpret_cast<const Boeing::MsgMap*>(m.c_str());
- return new MsgMap(sender, tstamp, bp->invoice, bp->seq, bp->x, bp->y,
- string((const char *)bp->map, bp->array_length), MsgMap::JPEG);
- }
- //messages to trader
-// case Boeing::TASK_CANCEL:
-// warn("packet") << "unhandled type: TASK_CANCEL " << endl;
-// break;
- //messages from trader
-// if(type == Boeing::INFO) {
-// warn("packet") << "unhandled type: INFO " << endl;
-// return NULL;
-// }
-// case Boeing::TASK_ACK:
-// warn("packet") << "unhandled type: TASK_ACK " << endl;
-// break;
-// case Boeing::TASK_DONE:
-// warn("packet") << "unhandled type: TASK_DONE " << endl;
-// break;
- //messages to mapserver/imageserver
-// case Boeing::MAP_ACK:
-// warn("packet") << "unhandled type: MAP_ACK " << endl;
-// break;
-// case Boeing::MAP_KEEPALIVE:
-// warn("packet") << "unhandled type: MAP_KEEPALIVE " << endl;
-// break;
- //messages from mapserver/imageserver
-// case Boeing::MAP_DIFF:
-// warn("packet") << "unhandled type: MAP_DIFF " << endl;
-// break;
-// case Boeing::MAP_FULL:
-// warn("packet") << "unhandled type: MAP_FULL " << endl;
-// break;
- warn("packet") << "unknown type: " << h->type << endl;
- return NULL;
-}
-
-void Msg::stamp(Boeing::MsgHeader& h)
-{
-#ifdef WIN32
- struct __timeb64 timebuffer;
- _ftime64(&timebuffer);
-#else
- struct timeb timebuffer;
- ftime(&timebuffer);
-#endif
- h.tstamp = timebuffer.time + (float)timebuffer.millitm/1000;
-}
-
-string Msg::getSender() const {return sender_;}
-
-// MsgCmd *************************************************************
-
-//normal instantiation
-MsgCmd::MsgCmd() : Msg(), taskID_(taskIDCounter++), priority_(defaultPriority) {}
-MsgCmd::MsgCmd(int priority, string sender)
-: Msg(sender), taskID_(taskIDCounter++), priority_(priority) {}
-//instantiation from Boeing packet
-MsgCmd::MsgCmd(string sender, double tstamp, int priority, int taskID)
-: Msg(sender, tstamp), taskID_(taskID), priority_(priority),
- status_(TaskStatus::IN_PROGRESS) {}
-
-int MsgCmd::getTaskID() const {return taskID_;}
-int MsgCmd::getPriority() const {return priority_;}
-
-void MsgCmd::setStatus(TaskStatus status) {status_ = status;}
-void MsgCmd::setStatus(const MsgRobDone* done) {
- status_ = done->getStatus();
- sender_ = done->getSender();
-}
-TaskStatus MsgCmd::getStatus() const {return status_;}
-
-MsgCmd* MsgCmd::interpretBoeingPlayAction(const Boeing::MsgCmdAction* m,
- const string& sender, double tstamp)
-{
- istringstream iaction(m->action);
- string action_head;
- iaction >> action_head;
- if(action_head == "halt")
- return new MsgCmdHalt(sender, tstamp, m->priority, m->taskid, m->action);
- if(action_head == "goto" || action_head == "home")
- return new MsgCmdGoTo(sender, tstamp, m->priority, m->taskid, m->action);
- if(action_head == "pause")
- return new MsgCmdPause(sender, tstamp, m->priority, m->taskid, m->action);
- if(action_head == "resume")
- return new MsgCmdResume(sender, tstamp, m->priority, m->taskid, m->action);
- if(action_head == "follow")
- return new MsgCmdFollow(sender, tstamp, m->priority, m->taskid, m->action);
- if(action_head == "cover")
- return new MsgCmdCover(sender, tstamp, m->priority, m->taskid, m->action);
- if(action_head == "setpos")
- return new MsgCmdSetPos(sender, tstamp, m->priority, m->taskid, m->action);
- warn("packet") << "unknown action head: " << action_head << endl;
- return NULL;
-}
-
-string MsgCmd::renderBoeingPacket() const
-{
- string retval;
- Boeing::MsgCmdAction bPacket =
- Boeing::MsgCmdAction::factory(render().c_str(), priority_, taskID_);
- retval.assign(reinterpret_cast<const char*>(&bPacket), bPacket.len);
- return retval;
-}
-
-string MsgCmd::render() const
-{
- ostringstream out;
- out << "MsgCmd: #" << taskID_;
- out << " sender(" << sender_;
- out << ") priority(" << priority_;
- out << ") tstamp(" << tstamp_ << ") ";
- out << renderBoeingPlayAction();
- return out.str();
-}
-
-// MsgCmdHalt *********************************************************
-
-//normal instantiation
-MsgCmdHalt::MsgCmdHalt(): MsgCmd() {}
-MsgCmdHalt::MsgCmdHalt(int priority): MsgCmd(priority) {}
-
-//instantiation from Boeing packet
-MsgCmdHalt::MsgCmdHalt(string sender, double tstamp, int priority, int taskID,
- string action)
-: MsgCmd(sender, tstamp, priority, taskID) {}
-
-string MsgCmdHalt::renderBoeingPlayAction() const {return "halt";}
-
-// MsgCmdGoTo *********************************************************
-
-//normal instantiation
-//turn radians
-MsgCmdGoTo::MsgCmdGoTo(float rad)
-: MsgCmd(), angle_(rad), useAngle_(true), absolute_(false) {}
-//move along a relative vector
-MsgCmdGoTo::MsgCmdGoTo(Point<float> loc, bool absolute)
-: MsgCmd(), loc_(loc), angle_(0), useAngle_(false), absolute_(absolute) {}
-MsgCmdGoTo::MsgCmdGoTo(Point<float> loc, float angle, bool useAngle, bool absolute, int priority, string sender)
-: MsgCmd(priority, sender), loc_(loc), angle_(angle), useAngle_(useAngle), absolute_(absolute) {}
-
-//instantiation from a Boeing packet
-MsgCmdGoTo::MsgCmdGoTo(string sender, double tstamp, int priority, int taskID, string action)
-: MsgCmd(sender, tstamp, priority, taskID) {
- MalformedPacketException e("MsgCmdGoTo", action);
- istringstream in(action);
- string token;
- if((in >> token).fail() || token != "goto") throw e;
- if((in >> token).fail()) throw e;
- if(token == "abs") absolute_ = true;
- else if(token == "rel") absolute_ = false;
- else throw e;
- if((in >> loc_).fail()) throw e;
- useAngle_ = !(in >> angle_).fail();
-}
-
-string MsgCmdGoTo::renderBoeingPlayAction() const {
- ostringstream out;
- out << "goto ";
- if(absolute_) out << "abs ";
- else out << "rel ";
- out << loc_;
- if(useAngle_) out << ' ' << angle_;
- return out.str();
-}
-
-float MsgCmdGoTo::getX() const {return loc_.x;}
-float MsgCmdGoTo::getY() const {return loc_.y;}
-float MsgCmdGoTo::getAngle() const {return angle_;}
-bool MsgCmdGoTo::useAngle() const {return useAngle_;}
-bool MsgCmdGoTo::isAbsolute() const {return absolute_;}
-bool MsgCmdGoTo::isRelative() const {return !absolute_;}
-
-// MsgCmdHome *********************************************************
-
-//normal instantiation
-MsgCmdHome::MsgCmdHome() : MsgCmd() {}
-MsgCmdHome::MsgCmdHome(int priority, string sender) : MsgCmd(priority, sender) {}
-
-//instantiation from a Boeing packet
-MsgCmdHome::MsgCmdHome(string sender, double tstamp, int priority, int taskID, string action)
-: MsgCmd(sender, tstamp, priority, taskID) {}
-
-string MsgCmdHome::renderBoeingPlayAction() const {return "home";}
-
-// MsgCmdPause ********************************************************
-
-//normal instantiation
-MsgCmdPause::MsgCmdPause(int priority, string sender) : MsgCmd(priority, sender) {}
-
-//instantiation from a Boeing packet
-MsgCmdPause::MsgCmdPause(string sender, double tstamp, int priority, int taskID, string action)
-: MsgCmd(sender, tstamp, priority, taskID) {}
-
-string MsgCmdPause::renderBoeingPlayAction() const {return "pause";}
-
-// MsgCmdResume *******************************************************
-
-//normal instantiation
-MsgCmdResume::MsgCmdResume(int priority, string sender) : MsgCmd(priority, sender) {}
-
-//instantiation from a Boeing packet
-MsgCmdResume::MsgCmdResume(string sender, double tstamp, int priority, int taskID, string action)
-: MsgCmd(sender, tstamp, priority, taskID) {}
-
-string MsgCmdResume::renderBoeingPlayAction() const {return "resum,e";}
-
-// MsgCmdFollow *******************************************************
-
-//normal instantiation
-MsgCmdFollow::MsgCmdFollow() : MsgCmd() {}
-MsgCmdFollow::MsgCmdFollow(int priority, string sender) : MsgCmd(priority, sender) {}
-
-//instantiation from a Boeing packet
-MsgCmdFollow::MsgCmdFollow(string sender, double tstamp, int priority, int taskID, string action)
-: MsgCmd(sender, tstamp, priority, taskID) {}
-
-string MsgCmdFollow::renderBoeingPlayAction() const {return "follow";}
-
-// MsgCmdCover ********************************************************
-
-//normal instantiations
-MsgCmdCover::MsgCmdCover(const Point<float>& lower_left, const Point<float>& upper_right, int priority, string sender)
-: MsgCmd(priority, sender), polygon_(4) {
- polygon_[0] = lower_left;
- polygon_[1] = Point<float>(lower_left.x, upper_right.y);
- polygon_[2] = upper_right;
- polygon_[3] = Point<float>(upper_right.x, lower_left.y);
-}
-
-MsgCmdCover::MsgCmdCover(float x1, float x2, float y1, float y2, int priority, string sender)
-: MsgCmd(priority, sender), polygon_(4) {
- polygon_[0] = Point<float>(x1, y1);
- polygon_[1] = Point<float>(x1, y2);
- polygon_[2] = Point<float>(x2, y2);
- polygon_[3] = Point<float>(x2, y1);
-}
-
-MsgCmdCover::MsgCmdCover(const geometry::Polygon<float>& polygon, int priority, string sender)
-: MsgCmd(priority, sender), polygon_(polygon) {}
-
-//instantiation from a Boeing packet
-MsgCmdCover::MsgCmdCover(string sender, double tstamp, int priority, int taskID, string action)
-: MsgCmd(sender, tstamp, priority, taskID) {
- MalformedPacketException e("MsgCmdCover", action);
- istringstream in(action);
- string token;
- if((in >> token).fail() || token != "cover") throw e;
- Point<float> p;
- if((in >> p).fail()) throw e; //there should be at least one cover point
- do {
- polygon_.push_back(p);
- in >> p;
- } while(!in.fail());
-}
-
-geometry::Polygon<float> MsgCmdCover::getPolygon() const {return polygon_;}
-
-string MsgCmdCover::renderBoeingPlayAction() const {
- ostringstream out;
- out << "cover ";
- for(geometry::Polygon<float>::const_iterator i = polygon_.begin(); i != polygon_.end(); i++) {
- if(i != polygon_.begin()) out << ' ';
- out << *i;
- }
- return out.str();
-}
-
-// MsgCmdSetPos *******************************************************
-
-//normal instantiation
-MsgCmdSetPos::MsgCmdSetPos(const Point<float>& loc, float angle, int priority, string sender)
-: MsgCmd(priority, sender), loc_(loc), angle_(angle) {}
-MsgCmdSetPos::MsgCmdSetPos(float x, float y, float angle, int priority, string sender)
-: MsgCmd(priority, sender), loc_(x, y), angle_(angle) {}
-
-//instantiation from a Boeing Packet
-MsgCmdSetPos::MsgCmdSetPos(string sender, double tstamp, int priority, int taskID, string action)
-: MsgCmd(sender, tstamp, priority, taskID) {
- MalformedPacketException e("MsgCmdSetPos", action);
- istringstream in(action);
- string token;
- if((in >> token).fail() || token != "setpos") throw e;
- if((in >> loc_).fail()) throw e;
- if((in >> angle_).fail()) throw e;
-}
-
-Point<float> MsgCmdSetPos::getLocation() const {return loc_;}
-float MsgCmdSetPos::getX() const {return loc_.x;}
-float MsgCmdSetPos::getY() const {return loc_.y;}
-float MsgCmdSetPos::getAngle() const {return angle_;}
-
-string MsgCmdSetPos::renderBoeingPlayAction() const {
- ostringstream out;
- out << "setpos " << loc_ << ' ' << angle_;
- return out.str();
-}
-
-// MsgReqLocation *****************************************************
-
-//normal instantiation
-MsgReqLocation::MsgReqLocation(string sender) : Msg(sender) {}
-
-//instatiation from a Boeing packet
-MsgReqLocation::MsgReqLocation(string sender, double tstamp) : Msg(sender, tstamp) {}
-
-string MsgReqLocation::render() const {return "reqlocation";}
-
-string MsgReqLocation::renderBoeingPacket() const {
- Boeing::MsgReqLocation packet =
- Boeing::MsgReqLocation::factory(1, taskIDCounter++);
- return string(reinterpret_cast<char *>(&packet), packet.len);
-}
-
-// MsgRobAck **********************************************************
-
-//normal instantiation
-MsgRobAck::MsgRobAck(int taskID, string sender) : Msg(sender), taskID_(taskID) {}
-
-//instatiation from a Boeing packet
-MsgRobAck::MsgRobAck(string sender, double tstamp, int taskID)
-: Msg(sender, tstamp), taskID_(taskID) {}
-
-string MsgRobAck::render() const {return "roback";}
-
-string MsgRobAck::renderBoeingPacket() const {
- Boeing::MsgRobAck packet = Boeing::MsgRobAck::factory(taskID_);
- return string(reinterpret_cast<char *>(&packet), packet.len);
-}
-
-// MsgRobActionAck ****************************************************
-
-//normal instantiation
-MsgRobActionAck::MsgRobActionAck(int taskID, TaskStatus status, string sender)
-: Msg(sender), taskID_(taskID), status_(status) {}
-
-//instantiation from a Boeing packet
-MsgRobActionAck::MsgRobActionAck(string sender, double tstamp, int taskID, int status)
-: Msg(sender, tstamp), taskID_(taskID),
- status_(TaskStatus::statusOfBoeing(status)) {}
-
-int MsgRobActionAck::getTaskID() const {return taskID_;}
-
-TaskStatus MsgRobActionAck::getStatus() const {return status_;}
-
-string MsgRobActionAck::render() const {
- ostringstream out;
- out << "robactionack: " << taskID_ << status_;
- return out.str();
-}
-
-string MsgRobActionAck::renderBoeingPacket() const {
- Boeing::MsgActionAck packet =
- Boeing::MsgActionAck::factory(taskID_, TaskStatus::boeingStatus(status_));
- return string(reinterpret_cast<char *>(&packet), packet.len);
-}
-
-// MsgRobDone *********************************************************
-
-//normal instantiation
-MsgRobDone::MsgRobDone(int taskID, TaskStatus status, string sender)
-: Msg(sender), taskID_(taskID), status_(status) {}
-
-//instantiation from a Boeing packet
-MsgRobDone::MsgRobDone(string sender, double tstamp, int taskID, TaskStatus status)
-: Msg(sender, tstamp), taskID_(taskID), status_(status) {}
-
-int MsgRobDone::getTaskID() const {return taskID_;}
-
-TaskStatus MsgRobDone::getStatus() const {return status_;}
-
-string MsgRobDone::render() const {
- ostringstream out;
- out << "robdone: " << taskID_ << ' ' << status_;
- return out.str();
-}
-
-string MsgRobDone::renderBoeingPacket() const {
- Boeing::MsgRobDone packet =
- Boeing::MsgRobDone::factory(taskID_, TaskStatus::boeingStatus(status_));
- return string(reinterpret_cast<char *>(&packet), packet.len);
-}
-
-// MsgRobLocation *****************************************************
-
-const float MsgRobLocation::tolerance = 0.05F; //5 cm tolerance to change-in position
-const float MsgRobLocation::angularTolerance = 0.03F; // ~2 deg tolerance
-
-//normal instantiation
-MsgRobLocation::MsgRobLocation()
-: Msg(), angle_(0), moving_(false) {}
-MsgRobLocation::MsgRobLocation(Point<float> loc, float angle, bool moving, string sender)
-: Msg(sender), loc_(loc), angle_(angle), moving_(moving) {}
-
-MsgRobLocation::MsgRobLocation(string sender, double tstamp, Point<float> loc, float angle, bool moving)
-: Msg(sender, tstamp), loc_(loc), angle_(angle), moving_(moving) {}
-
-Point<float> MsgRobLocation::getLocation() const {return loc_;}
-float MsgRobLocation::getX() const {return loc_.x;}
-float MsgRobLocation::getY() const {return loc_.y;}
-float MsgRobLocation::getAngle() const {return angle_;}
-bool MsgRobLocation::isMoving() const {return moving_;}
-
-bool MsgRobLocation::operator==(const MsgRobLocation& x) const {
- return (loc_-x.loc_).length() <= tolerance &&
- abs(angle_ - x.angle_) <= angularTolerance;
-}
-
-bool MsgRobLocation::operator!=(const MsgRobLocation& x) const {
- return (loc_-x.loc_).length() > tolerance ||
- abs(angle_ - x.angle_) <= angularTolerance;
-}
-
-string MsgRobLocation::render() const {
- ostringstream out;
- out << "roblocation: " << loc_ << angle_ << "rad "
- << (moving_? "MOVING": "STILL");
- return out.str();
-}
-
-string MsgRobLocation::renderBoeingPacket() const {
- Boeing::MsgRobLocation packet =
- Boeing::MsgRobLocation::factory(loc_.x, loc_.y, angle_, moving_);
- return string(reinterpret_cast<char*>(&packet), packet.len);
-}
-
-// MsgMapReq **********************************************************
-
-int MsgMapReq::invoiceCounter_ = 0;
-
-//normal instantiation
-MsgMapReq::MsgMapReq(string sender) : Msg(sender), invoice_(invoiceCounter_++) {}
-
-//instantiation from a Boeing packet
-MsgMapReq::MsgMapReq(string sender, double tstamp, int invoice)
-: Msg(sender, tstamp), invoice_(invoice) {}
-
-int MsgMapReq::getInvoice() const {return invoice_;}
-
-string MsgMapReq::render() const {
- ostringstream out;
- out << "mapreq: " << invoice_;
- return out.str();
-}
-
-string MsgMapReq::renderBoeingPacket() const {
- Boeing::MsgMapReq packet = Boeing::MsgMapReq::factory();
- return string(reinterpret_cast<char *>(&packet), packet.len);
-}
-
-// MsgMap *************************************************************
-
-//normal instantiation
-MsgMap::MsgMap(short invoice, int sequence, int width, int height, const string& imageData, MsgMap::Encoding encoding, string sender)
- : Msg(sender), invoice_(invoice), width_(width), height_(height), sequence_(sequence), encoding_(encoding), imageData_(imageData.begin(), imageData.end()) {}
-
-//instatiation from a Boeing packet
-MsgMap::MsgMap(string sender, double tstamp, short invoice, int sequence, int width, int height, const string& imageData, MsgMap::Encoding encoding)
- : Msg(sender, tstamp), invoice_(invoice), width_(width), height_(height), sequence_(sequence), encoding_(encoding), imageData_(imageData) {}
-
-int MsgMap::getWidth() const {return width_;}
-int MsgMap::getHeight() const {return height_;}
-short MsgMap::getInvoice() const {return invoice_;}
-int MsgMap::getSequence() const {return sequence_;}
-string MsgMap::getImageData() const {return imageData_;}
-size_t MsgMap::getImageDataSize() const {return imageData_.size();}
-MsgMap::Encoding MsgMap::getEncoding() const {return encoding_;}
-
-string MsgMap::render() const {
- ostringstream out;
- out << "msgmap: #" << invoice_ << ':' << sequence_ << ' ' << width_ << 'x' << height_;
- switch(encoding_) {
- case MsgMap::RAW:
- out << " RAW";
- break;
- case MsgMap::JPEG:
- out << " JPEG";
- break;
- default:
- out << " UNKNOWN(" << encoding_ << ')';
- }
- return out.str();
-}
-
-string MsgMap::renderBoeingPacket() const {
- //"compressed" form is potentially 4 times the size of the native form
- //this is probably unlikely, but we malloc the space initially
- Boeing::MsgMap* packet =
- (Boeing::MsgMap*) malloc(sizeof(Boeing::MsgMap)+4*imageData_.size());
- Boeing::MapMsgEncoding e;
- switch(encoding_) {
- case MsgMap::RAW:
- e = Boeing::MAP_RLE;
- break;
- case MsgMap::JPEG:
- e = Boeing::MAP_RAW;
- break;
- default: throw MalformedPacketException("MsgMap::renderBoeingPacket()", "");
- }
- Boeing::MsgMap::MsgMapFactory(e, packet, (const unsigned char*)imageData_.c_str(), (int)imageData_.size(), invoice_, sequence_, width_, height_);
- string spacket(reinterpret_cast<char*>(packet), packet->getSize());
- free(packet);
- return spacket;
-}
-
-// Stream Operators ***************************************************
-
-ostream& operator<<(ostream& out, const Msg* m)
-{
- return out << m->render();
-}
-
-/*
-ostream& operator<<(ostream& out, const Msg::Status& x)
-{
- switch(x)
- {
- case Msg::FAILED:
- out << "FAILED";
- break;
- case Msg::IN_PROGRESS:
- out << "IN PROGRESS";
- break;
- case Msg::SUCCEEDED:
- out << "SUCCEEDED";
- break;
- default:
- error << "unknown status: " << (int)x << endl;
- }
- return out;
-}
+#include "robot_packet2.h"
+#include "utils.h"
+#include "netutils.h"
+
+//these are for Msg::stamp
+#include <sys/types.h>
+#include <sys/timeb.h>
+
+#include <sstream>
+
+using namespace std;
+using namespace geometry;
+
+// MalformedPacketException *******************************************
+
+MalformedPacketException::MalformedPacketException(const string& context, const string& rep) throw() {
+ ostringstream e;
+ e << context << ": " << rep;
+ error = e.str();
+}
+
+MalformedPacketException::~MalformedPacketException() throw() {}
+
+const char* MalformedPacketException::what() throw() {return error.c_str();}
+
+// TaskStatus *********************************************************
+
+const char* TaskStatus::map_[] =
+ {"ABANDONED", "FAILED", "UNSENT", "UNACKED", "IN_PROGRESS", "SUCCEEDED"};
+
+TaskStatus::TaskStatus() : status_(TaskStatus::UNSENT) {}
+TaskStatus::TaskStatus(TaskStatus::Enum x) : status_(x) {}
+
+int TaskStatus::boeingStatus(TaskStatus x)
+{
+ switch(x.status_) {
+ case ABORTED: return Boeing::ABORTED;
+ case FAILED: return Boeing::FAILED;
+ case UNSENT:
+ case UNACKED:
+ case IN_PROGRESS: return Boeing::INPROGRESS;
+ case SUCCEEDED: return Boeing::SUCCEEDED;
+ default: error << "unknown status " << x;
+ }
+ return 0;
+}
+
+TaskStatus TaskStatus::statusOfBoeing(int x)
+{
+ if(x == Boeing::ABORTED) return TaskStatus(ABORTED);
+ if(x == Boeing::FAILED) return TaskStatus(FAILED);
+ if(x >= Boeing::SUCCEEDED) return SUCCEEDED;
+ return IN_PROGRESS;
+}
+
+TaskStatus TaskStatus::operator=(TaskStatus::Enum x) {
+ status_ = x;
+ return *this;
+}
+
+TaskStatus::operator const char *() const {return map_[status_];}
+
+bool TaskStatus::isInProgress() const {return status_ == IN_PROGRESS;}
+bool TaskStatus::isFailed() const {return status_ == FAILED;}
+bool TaskStatus::isAborted() const {return status_ == ABORTED;}
+bool TaskStatus::isSuccess() const {return status_ == SUCCEEDED;}
+
+// Msg ****************************************************************
+
+int Msg::taskIDCounter = 0;
+const int Msg::defaultPriority = 1;
+
+//normal instantiation
+Msg::Msg(string sender) : sender_(sender) {}
+//instantiation from Boeing packet
+Msg::Msg(string sender, double tstamp) : sender_(sender), tstamp_(tstamp) {}
+
+Msg::Msg(const Msg& m) : sender_(m.sender_), tstamp_(m.tstamp_) {}
+
+Msg::~Msg() {}
+
+Msg* Msg::interpretBoeingPacket(const string& m, const string& sender)
+{
+ const Boeing::MsgHeader *h =
+ reinterpret_cast<const Boeing::MsgHeader*>(m.c_str());
+ double tstamp = h->tstamp;
+ int type = h->type;
+ //messages to robots
+ if(type == Boeing::ROB_ACTION_ECHO || type == Boeing::CMD_ACTION) {
+ debug("packet") << "got: CMD_ACTION or ROB_ACTION_ECHO" << endl;
+ return MsgCmd::interpretBoeingPlayAction(
+ reinterpret_cast<const Boeing::MsgCmdAction*>(m.c_str()), sender, tstamp);
+ }
+ if(type == Boeing::CMD_COVER) {
+ warn("packet") << "unhandled type: CMD_COVER " << endl;
+ return NULL;
+ }
+ if(type == Boeing::CMD_FOLLOW) {
+ warn("packet") << "unhandled type: CMD_FOLLOW " << endl;
+ return NULL;
+ }
+ if(type == Boeing::CMD_GOTO) {
+ warn("packet") << "unhandled type: CMD_GOTO " << endl;
+ return NULL;
+ }
+ if(type == Boeing::CMD_HALT) {
+ warn("packet") << "unhandled type: CMD_HALT " << endl;
+ return NULL;
+ }
+ if(type == Boeing::CMD_HOME) {
+ warn("packet") << "unhandled type: CMD_HOME " << endl;
+ return NULL;
+ }
+ if(type == Boeing::CMD_PAUSE) {
+ warn("packet") << "unhandled type: CMD_PAUSE " << endl;
+ return NULL;
+ }
+ if(type == Boeing::CMD_RESUME) {
+ warn("packet") << "unhandled type: CMD_RESUME " << endl;
+ return NULL;
+ }
+ if(type == Boeing::CMD_SETPOS) {
+ warn("packet") << "unhandled type: CMD_SETPOS " << endl;
+ return NULL;
+ }
+ if(type == Boeing::REQ_LOCATION) {
+ debug("packet") << "got: REQ_LOCATION" << endl;
+ return new MsgReqLocation(sender, tstamp);
+ }
+ if(type == Boeing::REQ_IMAGE) {
+ debug("packet") << "got: REQ_IMAGE" << endl;
+ return new MsgMapReq(sender, tstamp,
+ reinterpret_cast<const Boeing::MsgMapReq*>(m.c_str())->invoice);
+ }
+ //messages from robots
+ if(type == Boeing::ROB_LOCATION) {
+ debug("packet") << "got ROB_LOCATION" << endl;
+ const Boeing::MsgRobLocation* brl =
+ reinterpret_cast<const Boeing::MsgRobLocation*>(m.c_str());
+ return new MsgRobLocation(sender, brl->tstamp,
+ geometry::Point<float>(brl->x, brl->y), brl->angle, (brl->moving != 0));
+ }
+ if(type == Boeing::ROB_ACK) {
+ debug("packet") << "got: ROB_ACK" << endl;
+ return new MsgRobAck(sender, tstamp,
+ reinterpret_cast<const Boeing::MsgRobAck*>(m.c_str())->taskid);
+ }
+ if(type == Boeing::ROB_ACTION_ACK) {
+ warn("packet") << "unhandled type: ROB_ACTION_ACK " << h->type << endl;
+ debug("packet") << "got: ROB_ACTION_ACK" << endl;
+ const Boeing::MsgActionAck* bp = reinterpret_cast<const Boeing::MsgActionAck*>(m.c_str());
+ return new MsgRobActionAck(sender, tstamp, bp->taskid, (bp->status == Boeing::SUCCEEDED));
+ }
+ if(type == Boeing::ROB_DONE) {
+ debug("packet") << "got: ROB_DONE" << endl;
+ const Boeing::MsgRobDone* bp = reinterpret_cast<const Boeing::MsgRobDone*>(m.c_str());
+ if(bp->status == Boeing::SUCCEEDED)
+ return new MsgRobDone(sender, tstamp, bp->taskid, TaskStatus::SUCCEEDED);
+ else if(bp->status == Boeing::FAILED)
+ return new MsgRobDone(sender, tstamp, bp->taskid, TaskStatus::FAILED);
+ else if(bp->status == Boeing::ABORTED)
+ return new MsgRobDone(sender, tstamp, bp->taskid, TaskStatus::ABORTED);
+ else {
+ error << "couldn't get Boeing::ROB_DONE status" << endl;
+ return NULL;
+ }
+ }
+ if(type == Boeing::ROB_PLAY_HALT) {
+ warn("packet") << "unhandled type: ROB_PLAY_HALT " << endl;
+ return NULL;
+ }
+ if(type == Boeing::ROB_IMAGE) {
+ debug("packet") << "got: ROB_IMAGE" << endl;
+ const Boeing::MsgMap* bp = reinterpret_cast<const Boeing::MsgMap*>(m.c_str());
+ return new MsgMap(sender, tstamp, bp->invoice, bp->seq, bp->x, bp->y,
+ string((const char *)bp->map, bp->array_length), MsgMap::JPEG);
+ }
+ //messages to trader
+// case Boeing::TASK_CANCEL:
+// warn("packet") << "unhandled type: TASK_CANCEL " << endl;
+// break;
+ //messages from trader
+// if(type == Boeing::INFO) {
+// warn("packet") << "unhandled type: INFO " << endl;
+// return NULL;
+// }
+// case Boeing::TASK_ACK:
+// warn("packet") << "unhandled type: TASK_ACK " << endl;
+// break;
+// case Boeing::TASK_DONE:
+// warn("packet") << "unhandled type: TASK_DONE " << endl;
+// break;
+ //messages to mapserver/imageserver
+// case Boeing::MAP_ACK:
+// warn("packet") << "unhandled type: MAP_ACK " << endl;
+// break;
+// case Boeing::MAP_KEEPALIVE:
+// warn("packet") << "unhandled type: MAP_KEEPALIVE " << endl;
+// break;
+ //messages from mapserver/imageserver
+// case Boeing::MAP_DIFF:
+// warn("packet") << "unhandled type: MAP_DIFF " << endl;
+// break;
+// case Boeing::MAP_FULL:
+// warn("packet") << "unhandled type: MAP_FULL " << endl;
+// break;
+ warn("packet") << "unknown type: " << h->type << endl;
+ return NULL;
+}
+
+void Msg::stamp(Boeing::MsgHeader& h)
+{
+#ifdef WIN32
+ struct __timeb64 timebuffer;
+ _ftime64(&timebuffer);
+#else
+ struct timeb timebuffer;
+ ftime(&timebuffer);
+#endif
+ h.tstamp = timebuffer.time + (float)timebuffer.millitm/1000;
+}
+
+string Msg::getSender() const {return sender_;}
+
+// MsgCmd *************************************************************
+
+//normal instantiation
+MsgCmd::MsgCmd() : Msg(), taskID_(taskIDCounter++), priority_(defaultPriority) {}
+MsgCmd::MsgCmd(int priority, string sender)
+: Msg(sender), taskID_(taskIDCounter++), priority_(priority) {}
+//instantiation from Boeing packet
+MsgCmd::MsgCmd(string sender, double tstamp, int priority, int taskID)
+: Msg(sender, tstamp), taskID_(taskID), priority_(priority),
+ status_(TaskStatus::IN_PROGRESS) {}
+
+int MsgCmd::getTaskID() const {return taskID_;}
+int MsgCmd::getPriority() const {return priority_;}
+
+void MsgCmd::setStatus(TaskStatus status) {status_ = status;}
+void MsgCmd::setStatus(const MsgRobDone* done) {
+ status_ = done->getStatus();
+ sender_ = done->getSender();
+}
+TaskStatus MsgCmd::getStatus() const {return status_;}
+
+MsgCmd* MsgCmd::interpretBoeingPlayAction(const Boeing::MsgCmdAction* m,
+ const string& sender, double tstamp)
+{
+ istringstream iaction(m->action);
+ string action_head;
+ iaction >> action_head;
+ if(action_head == "halt")
+ return new MsgCmdHalt(sender, tstamp, m->priority, m->taskid, m->action);
+ if(action_head == "goto" || action_head == "home")
+ return new MsgCmdGoTo(sender, tstamp, m->priority, m->taskid, m->action);
+ if(action_head == "pause")
+ return new MsgCmdPause(sender, tstamp, m->priority, m->taskid, m->action);
+ if(action_head == "resume")
+ return new MsgCmdResume(sender, tstamp, m->priority, m->taskid, m->action);
+ if(action_head == "follow")
+ return new MsgCmdFollow(sender, tstamp, m->priority, m->taskid, m->action);
+ if(action_head == "cover")
+ return new MsgCmdCover(sender, tstamp, m->priority, m->taskid, m->action);
+ if(action_head == "setpos")
+ return new MsgCmdSetPos(sender, tstamp, m->priority, m->taskid, m->action);
+ warn("packet") << "unknown action head: " << action_head << endl;
+ return NULL;
+}
+
+string MsgCmd::renderBoeingPacket() const
+{
+ string retval;
+ Boeing::MsgCmdAction bPacket =
+ Boeing::MsgCmdAction::factory(render().c_str(), priority_, taskID_);
+ retval.assign(reinterpret_cast<const char*>(&bPacket), bPacket.len);
+ return retval;
+}
+
+string MsgCmd::render() const
+{
+ ostringstream out;
+ out << "MsgCmd: #" << taskID_;
+ out << " sender(" << sender_;
+ out << ") priority(" << priority_;
+ out << ") tstamp(" << tstamp_ << ") ";
+ out << renderBoeingPlayAction();
+ return out.str();
+}
+
+// MsgCmdHalt *********************************************************
+
+//normal instantiation
+MsgCmdHalt::MsgCmdHalt(): MsgCmd() {}
+MsgCmdHalt::MsgCmdHalt(int priority): MsgCmd(priority) {}
+
+//instantiation from Boeing packet
+MsgCmdHalt::MsgCmdHalt(string sender, double tstamp, int priority, int taskID,
+ string action)
+: MsgCmd(sender, tstamp, priority, taskID) {}
+
+string MsgCmdHalt::renderBoeingPlayAction() const {return "halt";}
+
+// MsgCmdGoTo *********************************************************
+
+//normal instantiation
+//turn radians
+MsgCmdGoTo::MsgCmdGoTo(float rad)
+: MsgCmd(), angle_(rad), useAngle_(true), absolute_(false) {}
+//move along a relative vector
+MsgCmdGoTo::MsgCmdGoTo(Point<float> loc, bool absolute)
+: MsgCmd(), loc_(loc), angle_(0), useAngle_(false), absolute_(absolute) {}
+MsgCmdGoTo::MsgCmdGoTo(Point<float> loc, float angle, bool useAngle, bool absolute, int priority, string sender)
+: MsgCmd(priority, sender), loc_(loc), angle_(angle), useAngle_(useAngle), absolute_(absolute) {}
+
+//instantiation from a Boeing packet
+MsgCmdGoTo::MsgCmdGoTo(string sender, double tstamp, int priority, int taskID, string action)
+: MsgCmd(sender, tstamp, priority, taskID) {
+ MalformedPacketException e("MsgCmdGoTo", action);
+ istringstream in(action);
+ string token;
+ if((in >> token).fail() || token != "goto") throw e;
+ if((in >> token).fail()) throw e;
+ if(token == "abs") absolute_ = true;
+ else if(token == "rel") absolute_ = false;
+ else throw e;
+ if((in >> loc_).fail()) throw e;
+ useAngle_ = !(in >> angle_).fail();
+}
+
+string MsgCmdGoTo::renderBoeingPlayAction() const {
+ ostringstream out;
+ out << "goto ";
+ if(absolute_) out << "abs ";
+ else out << "rel ";
+ out << loc_;
+ if(useAngle_) out << ' ' << angle_;
+ return out.str();
+}
+
+float MsgCmdGoTo::getX() const {return loc_.x;}
+float MsgCmdGoTo::getY() const {return loc_.y;}
+float MsgCmdGoTo::getAngle() const {return angle_;}
+bool MsgCmdGoTo::useAngle() const {return useAngle_;}
+bool MsgCmdGoTo::isAbsolute() const {return absolute_;}
+bool MsgCmdGoTo::isRelative() const {return !absolute_;}
+
+// MsgCmdHome *********************************************************
+
+//normal instantiation
+MsgCmdHome::MsgCmdHome() : MsgCmd() {}
+MsgCmdHome::MsgCmdHome(int priority, string sender) : MsgCmd(priority, sender) {}
+
+//instantiation from a Boeing packet
+MsgCmdHome::MsgCmdHome(string sender, double tstamp, int priority, int taskID, string action)
+: MsgCmd(sender, tstamp, priority, taskID) {}
+
+string MsgCmdHome::renderBoeingPlayAction() const {return "home";}
+
+// MsgCmdPause ********************************************************
+
+//normal instantiation
+MsgCmdPause::MsgCmdPause(int priority, string sender) : MsgCmd(priority, sender) {}
+
+//instantiation from a Boeing packet
+MsgCmdPause::MsgCmdPause(string sender, double tstamp, int priority, int taskID, string action)
+: MsgCmd(sender, tstamp, priority, taskID) {}
+
+string MsgCmdPause::renderBoeingPlayAction() const {return "pause";}
+
+// MsgCmdResume *******************************************************
+
+//normal instantiation
+MsgCmdResume::MsgCmdResume(int priority, string sender) : MsgCmd(priority, sender) {}
+
+//instantiation from a Boeing packet
+MsgCmdResume::MsgCmdResume(string sender, double tstamp, int priority, int taskID, string action)
+: MsgCmd(sender, tstamp, priority, taskID) {}
+
+string MsgCmdResume::renderBoeingPlayAction() const {return "resum,e";}
+
+// MsgCmdFollow *******************************************************
+
+//normal instantiation
+MsgCmdFollow::MsgCmdFollow() : MsgCmd() {}
+MsgCmdFollow::MsgCmdFollow(int priority, string sender) : MsgCmd(priority, sender) {}
+
+//instantiation from a Boeing packet
+MsgCmdFollow::MsgCmdFollow(string sender, double tstamp, int priority, int taskID, string action)
+: MsgCmd(sender, tstamp, priority, taskID) {}
+
+string MsgCmdFollow::renderBoeingPlayAction() const {return "follow";}
+
+// MsgCmdCover ********************************************************
+
+//normal instantiations
+MsgCmdCover::MsgCmdCover(const Point<float>& lower_left, const Point<float>& upper_right, int priority, string sender)
+: MsgCmd(priority, sender), polygon_(4) {
+ polygon_[0] = lower_left;
+ polygon_[1] = Point<float>(lower_left.x, upper_right.y);
+ polygon_[2] = upper_right;
+ polygon_[3] = Point<float>(upper_right.x, lower_left.y);
+}
+
+MsgCmdCover::MsgCmdCover(float x1, float x2, float y1, float y2, int priority, string sender)
+: MsgCmd(priority, sender), polygon_(4) {
+ polygon_[0] = Point<float>(x1, y1);
+ polygon_[1] = Point<float>(x1, y2);
+ polygon_[2] = Point<float>(x2, y2);
+ polygon_[3] = Point<float>(x2, y1);
+}
+
+MsgCmdCover::MsgCmdCover(const geometry::Polygon<float>& polygon, int priority, string sender)
+: MsgCmd(priority, sender), polygon_(polygon) {}
+
+//instantiation from a Boeing packet
+MsgCmdCover::MsgCmdCover(string sender, double tstamp, int priority, int taskID, string action)
+: MsgCmd(sender, tstamp, priority, taskID) {
+ MalformedPacketException e("MsgCmdCover", action);
+ istringstream in(action);
+ string token;
+ if((in >> token).fail() || token != "cover") throw e;
+ Point<float> p;
+ if((in >> p).fail()) throw e; //there should be at least one cover point
+ do {
+ polygon_.push_back(p);
+ in >> p;
+ } while(!in.fail());
+}
+
+geometry::Polygon<float> MsgCmdCover::getPolygon() const {return polygon_;}
+
+string MsgCmdCover::renderBoeingPlayAction() const {
+ ostringstream out;
+ out << "cover ";
+ for(geometry::Polygon<float>::const_iterator i = polygon_.begin(); i != polygon_.end(); i++) {
+ if(i != polygon_.begin()) out << ' ';
+ out << *i;
+ }
+ return out.str();
+}
+
+// MsgCmdSetPos *******************************************************
+
+//normal instantiation
+MsgCmdSetPos::MsgCmdSetPos(const Point<float>& loc, float angle, int priority, string sender)
+: MsgCmd(priority, sender), loc_(loc), angle_(angle) {}
+MsgCmdSetPos::MsgCmdSetPos(float x, float y, float angle, int priority, string sender)
+: MsgCmd(priority, sender), loc_(x, y), angle_(angle) {}
+
+//instantiation from a Boeing Packet
+MsgCmdSetPos::MsgCmdSetPos(string sender, double tstamp, int priority, int taskID, string action)
+: MsgCmd(sender, tstamp, priority, taskID) {
+ MalformedPacketException e("MsgCmdSetPos", action);
+ istringstream in(action);
+ string token;
+ if((in >> token).fail() || token != "setpos") throw e;
+ if((in >> loc_).fail()) throw e;
+ if((in >> angle_).fail()) throw e;
+}
+
+Point<float> MsgCmdSetPos::getLocation() const {return loc_;}
+float MsgCmdSetPos::getX() const {return loc_.x;}
+float MsgCmdSetPos::getY() const {return loc_.y;}
+float MsgCmdSetPos::getAngle() const {return angle_;}
+
+string MsgCmdSetPos::renderBoeingPlayAction() const {
+ ostringstream out;
+ out << "setpos " << loc_ << ' ' << angle_;
+ return out.str();
+}
+
+// MsgReqLocation *****************************************************
+
+//normal instantiation
+MsgReqLocation::MsgReqLocation(string sender) : Msg(sender) {}
+
+//instatiation from a Boeing packet
+MsgReqLocation::MsgReqLocation(string sender, double tstamp) : Msg(sender, tstamp) {}
+
+string MsgReqLocation::render() const {return "reqlocation";}
+
+string MsgReqLocation::renderBoeingPacket() const {
+ Boeing::MsgReqLocation packet =
+ Boeing::MsgReqLocation::factory(1, taskIDCounter++);
+ return string(reinterpret_cast<char *>(&packet), packet.len);
+}
+
+// MsgRobAck **********************************************************
+
+//normal instantiation
+MsgRobAck::MsgRobAck(int taskID, string sender) : Msg(sender), taskID_(taskID) {}
+
+//instatiation from a Boeing packet
+MsgRobAck::MsgRobAck(string sender, double tstamp, int taskID)
+: Msg(sender, tstamp), taskID_(taskID) {}
+
+string MsgRobAck::render() const {return "roback";}
+
+string MsgRobAck::renderBoeingPacket() const {
+ Boeing::MsgRobAck packet = Boeing::MsgRobAck::factory(taskID_);
+ return string(reinterpret_cast<char *>(&packet), packet.len);
+}
+
+// MsgRobActionAck ****************************************************
+
+//normal instantiation
+MsgRobActionAck::MsgRobActionAck(int taskID, TaskStatus status, string sender)
+: Msg(sender), taskID_(taskID), status_(status) {}
+
+//instantiation from a Boeing packet
+MsgRobActionAck::MsgRobActionAck(string sender, double tstamp, int taskID, int status)
+: Msg(sender, tstamp), taskID_(taskID),
+ status_(TaskStatus::statusOfBoeing(status)) {}
+
+int MsgRobActionAck::getTaskID() const {return taskID_;}
+
+TaskStatus MsgRobActionAck::getStatus() const {return status_;}
+
+string MsgRobActionAck::render() const {
+ ostringstream out;
+ out << "robactionack: " << taskID_ << status_;
+ return out.str();
+}
+
+string MsgRobActionAck::renderBoeingPacket() const {
+ Boeing::MsgActionAck packet =
+ Boeing::MsgActionAck::factory(taskID_, TaskStatus::boeingStatus(status_));
+ return string(reinterpret_cast<char *>(&packet), packet.len);
+}
+
+// MsgRobDone *********************************************************
+
+//normal instantiation
+MsgRobDone::MsgRobDone(int taskID, TaskStatus status, string sender)
+: Msg(sender), taskID_(taskID), status_(status) {}
+
+//instantiation from a Boeing packet
+MsgRobDone::MsgRobDone(string sender, double tstamp, int taskID, TaskStatus status)
+: Msg(sender, tstamp), taskID_(taskID), status_(status) {}
+
+int MsgRobDone::getTaskID() const {return taskID_;}
+
+TaskStatus MsgRobDone::getStatus() const {return status_;}
+
+string MsgRobDone::render() const {
+ ostringstream out;
+ out << "robdone: " << taskID_ << ' ' << status_;
+ return out.str();
+}
+
+string MsgRobDone::renderBoeingPacket() const {
+ Boeing::MsgRobDone packet =
+ Boeing::MsgRobDone::factory(taskID_, TaskStatus::boeingStatus(status_));
+ return string(reinterpret_cast<char *>(&packet), packet.len);
+}
+
+// MsgRobLocation *****************************************************
+
+const float MsgRobLocation::tolerance = 0.05F; //5 cm tolerance to change-in position
+const float MsgRobLocation::angularTolerance = 0.03F; // ~2 deg tolerance
+
+//normal instantiation
+MsgRobLocation::MsgRobLocation()
+: Msg(), angle_(0), moving_(false) {}
+MsgRobLocation::MsgRobLocation(Point<float> loc, float angle, bool moving, string sender)
+: Msg(sender), loc_(loc), angle_(angle), moving_(moving) {}
+
+MsgRobLocation::MsgRobLocation(string sender, double tstamp, Point<float> loc, float angle, bool moving)
+: Msg(sender, tstamp), loc_(loc), angle_(angle), moving_(moving) {}
+
+Point<float> MsgRobLocation::getLocation() const {return loc_;}
+float MsgRobLocation::getX() const {return loc_.x;}
+float MsgRobLocation::getY() const {return loc_.y;}
+float MsgRobLocation::getAngle() const {return angle_;}
+bool MsgRobLocation::isMoving() const {return moving_;}
+
+bool MsgRobLocation::operator==(const MsgRobLocation& x) const {
+ return (loc_-x.loc_).length() <= tolerance &&
+ abs(angle_ - x.angle_) <= angularTolerance;
+}
+
+bool MsgRobLocation::operator!=(const MsgRobLocation& x) const {
+ return (loc_-x.loc_).length() > tolerance ||
+ abs(angle_ - x.angle_) <= angularTolerance;
+}
+
+string MsgRobLocation::render() const {
+ ostringstream out;
+ out << "roblocation: " << loc_ << angle_ << "rad "
+ << (moving_? "MOVING": "STILL");
+ return out.str();
+}
+
+string MsgRobLocation::renderBoeingPacket() const {
+ Boeing::MsgRobLocation packet =
+ Boeing::MsgRobLocation::factory(loc_.x, loc_.y, angle_, moving_);
+ return string(reinterpret_cast<char*>(&packet), packet.len);
+}
+
+// MsgMapReq **********************************************************
+
+int MsgMapReq::invoiceCounter_ = 0;
+
+//normal instantiation
+MsgMapReq::MsgMapReq(string sender) : Msg(sender), invoice_(invoiceCounter_++) {}
+
+//instantiation from a Boeing packet
+MsgMapReq::MsgMapReq(string sender, double tstamp, int invoice)
+: Msg(sender, tstamp), invoice_(invoice) {}
+
+int MsgMapReq::getInvoice() const {return invoice_;}
+
+string MsgMapReq::render() const {
+ ostringstream out;
+ out << "mapreq: " << invoice_;
+ return out.str();
+}
+
+string MsgMapReq::renderBoeingPacket() const {
+ Boeing::MsgMapReq packet = Boeing::MsgMapReq::factory();
+ return string(reinterpret_cast<char *>(&packet), packet.len);
+}
+
+// MsgMap *************************************************************
+
+//normal instantiation
+MsgMap::MsgMap(short invoice, int sequence, int width, int height, const string& imageData, MsgMap::Encoding encoding, string sender)
+ : Msg(sender), invoice_(invoice), width_(width), height_(height), sequence_(sequence), encoding_(encoding), imageData_(imageData.begin(), imageData.end()) {}
+
+//instatiation from a Boeing packet
+MsgMap::MsgMap(string sender, double tstamp, short invoice, int sequence, int width, int height, const string& imageData, MsgMap::Encoding encoding)
+ : Msg(sender, tstamp), invoice_(invoice), width_(width), height_(height), sequence_(sequence), encoding_(encoding), imageData_(imageData) {}
+
+int MsgMap::getWidth() const {return width_;}
+int MsgMap::getHeight() const {return height_;}
+short MsgMap::getInvoice() const {return invoice_;}
+int MsgMap::getSequence() const {return sequence_;}
+string MsgMap::getImageData() const {return imageData_;}
+size_t MsgMap::getImageDataSize() const {return imageData_.size();}
+MsgMap::Encoding MsgMap::getEncoding() const {return encoding_;}
+
+string MsgMap::render() const {
+ ostringstream out;
+ out << "msgmap: #" << invoice_ << ':' << sequence_ << ' ' << width_ << 'x' << height_;
+ switch(encoding_) {
+ case MsgMap::RAW:
+ out << " RAW";
+ break;
+ case MsgMap::JPEG:
+ out << " JPEG";
+ break;
+ default:
+ out << " UNKNOWN(" << encoding_ << ')';
+ }
+ return out.str();
+}
+
+string MsgMap::renderBoeingPacket() const {
+ //"compressed" form is potentially 4 times the size of the native form
+ //this is probably unlikely, but we malloc the space initially
+ Boeing::MsgMap* packet =
+ (Boeing::MsgMap*) malloc(sizeof(Boeing::MsgMap)+4*imageData_.size());
+ Boeing::MapMsgEncoding e;
+ switch(encoding_) {
+ case MsgMap::RAW:
+ e = Boeing::MAP_RLE;
+ break;
+ case MsgMap::JPEG:
+ e = Boeing::MAP_RAW;
+ break;
+ default: throw MalformedPacketException("MsgMap::renderBoeingPacket()", "");
+ }
+ Boeing::MsgMap::MsgMapFactory(e, packet, (const unsigned char*)imageData_.c_str(), (int)imageData_.size(), invoice_, sequence_, width_, height_);
+ string spacket(reinterpret_cast<char*>(packet), packet->getSize());
+ free(packet);
+ return spacket;
+}
+
+// Stream Operators ***************************************************
+
+ostream& operator<<(ostream& out, const Msg* m)
+{
+ return out << m->render();
+}
+
+/*
+ostream& operator<<(ostream& out, const Msg::Status& x)
+{
+ switch(x)
+ {
+ case Msg::FAILED:
+ out << "FAILED";
+ break;
+ case Msg::IN_PROGRESS:
+ out << "IN PROGRESS";
+ break;
+ case Msg::SUCCEEDED:
+ out << "SUCCEEDED";
+ break;
+ default:
+ error << "unknown status: " << (int)x << endl;
+ }
+ return out;
+}
*/
Modified: TeamTalk/Agents/TeamTalkBackend/robot-galaxy_adapter.cpp
===================================================================
--- TeamTalk/Agents/TeamTalkBackend/robot-galaxy_adapter.cpp 2007-04-05 20:17:36 UTC (rev 574)
+++ TeamTalk/Agents/TeamTalkBackend/robot-galaxy_adapter.cpp 2007-04-06 20:09:41 UTC (rev 575)
@@ -59,10 +59,6 @@
map<string, string> subs;
{
ostringstream gname;
- /*
- for(set<Agent>::const_iterator i = agents_.begin(); i != agents_.end(); i++) {
- gname << " (" << tolower(i->getName()) << ')' << endl;
- */
for(vector<string>::const_iterator i = names.begin(); i != names.end(); i++) {
gname << " (" << tolower(*i) << ')' << endl;
}
@@ -70,11 +66,12 @@
debug << ' ' << gname.str();
}
debug << endl;
- Agent::writeSpecializedConfig("..\\..\\Resources\\Grammar\\zap2Task", "gra",
+ Agent::writeSpecializedConfig("..\\..\\Resources\\Grammar\\TeamTalkTask", "gra",
subs);
PROCESS_INFORMATION lm_build_proc =
- spawn(true, "Language Build", "..\\..\\Resources\\MakeLM", "perl", "makelm.pl");
+ spawn(true, "Language Build", "..\\..\\Tools\\MakeLM", "perl",
+ "makelm.pl TeamTalk ..\\..\\Resources");
}
void GalaxyRobots::traderlistener(void *p)
Modified: TeamTalk/Resources/DecoderConfig/female-16khz.arg
===================================================================
--- TeamTalk/Resources/DecoderConfig/female-16khz.arg 2007-04-05 20:17:36 UTC (rev 574)
+++ TeamTalk/Resources/DecoderConfig/female-16khz.arg 2007-04-06 20:09:41 UTC (rev 575)
@@ -23,8 +23,8 @@
-fwdflatbeam 1e-8
-fwdflatnwbeam 3e-4
-rescorelw 9.5
- -lmfn LanguageModel\zap2LM.arpa
- -dictfn Dictionary\zap2.dict.reduced_phoneset
+ -lmfn LanguageModel\TeamTalkLM.arpa
+ -dictfn Dictionary\TeamTalk.dict.reduced_phoneset
-ndictfn Dictionary\noise.dict
-phnfn HMM-16khz.ss/phone
-mapfn HMM-16khz.ss/map
Modified: TeamTalk/Resources/DecoderConfig/male-16khz.arg
===================================================================
--- TeamTalk/Resources/DecoderConfig/male-16khz.arg 2007-04-05 20:17:36 UTC (rev 574)
+++ TeamTalk/Resources/DecoderConfig/male-16khz.arg 2007-04-06 20:09:41 UTC (rev 575)
@@ -23,8 +23,8 @@
-fwdflatbeam 1e-8
-fwdflatnwbeam 3e-4
-rescorelw 9.5
- -lmfn LanguageModel\zap2LM.arpa
- -dictfn Dictionary\zap2.dict.reduced_phoneset
+ -lmfn LanguageModel\TeamTalkLM.arpa
+ -dictfn Dictionary\TeamTalk.dict.reduced_phoneset
-ndictfn Dictionary\noise.dict
-phnfn HMM-16khz.ss/phone
-mapfn HMM-16khz.ss/map
Copied: TeamTalk/Resources/Grammar/TeamTalkTask-template.gra (from rev 574, TeamTalk/Resources/Grammar/zap2Task-template.gra)
===================================================================
--- TeamTalk/Resources/Grammar/TeamTalkTask-template.gra (rev 0)
+++ TeamTalk/Resources/Grammar/TeamTalkTask-template.gra 2007-04-06 20:09:41 UTC (rev 575)
@@ -0,0 +1,360 @@
+###################################################################
+#
+# Z A P T A S K G R A M M A R
+#
+# HISTORY: -------------------------------------------------------
+#
+# [2003-03-08] (sison): started working on this
+#
+###################################################################
+
+[RobotName]
+ (everyone)
+%%RobotNames%%;
+
+[OBJ-Robot]
+ ([RobotName])
+;
+
+[HumanFollowCommand]
+ (*[RobotName] FOLLOW [OBJ-Robot])
+
+FOLLOW
+ (join)
+ (follow)
+ (find)
+;
+
+[HumanPauseCommand]
+ (*[RobotName] pause)
+;
+
+[HumanContinueCommand]
+ (*[RobotName] continue)
+;
+
+[HumanReportCommand]
+ (*[RobotName] report)
+ ([RobotName])
+;
+
+[HumanLocationQuery]
+ (*[RobotName] where are you)
+;
+
+[HumanHaltCommand]
+ (*[RobotName] all stop)
+;
+
+[TurnDirection]
+ (right *[AngularQualifier])
+ (left *[AngularQualifier])
+ (around)
+;
+
+[MoveDirection]
+ (right *[AngularQualifier])
+ (left *[AngularQualifier])
+ (straight)
+ (forward)
+ (forwards)
+ (back)
+ (backward)
+ (backwards)
+;
+
+[AngularQualifier]
+ ([Number-180-by5] degrees)
+;
+
+[Number-180-by5]
+ (five)
+ (ten)
+ (fifteen)
+ (twenty *five)
+ (thirty *five)
+ (forty *five)
+ (fifty *five)
+ (sixty *five)
+ (seventy *five)
+ (eighty *five)
+ (ninety *five)
+ (HUNDRED)
+ (HUNDRED *and five)
+ (HUNDRED *and ten)
+ (HUNDRED *and fifteen)
+ (HUNDRED *and twenty *five)
+ (HUNDRED *and thirty *five)
+ (HUNDRED *and fourty *five)
+ (HUNDRED *and fifty *five)
+ (HUNDRED *and sixty *five)
+ (HUNDRED *and seventy *five)
+ (HUNDRED *and eighty)
+
+HUNDRED
+ (a hundred)
+ (one hundred)
+;
+
+[AbsoluteDistance]
+ ([Number-20] [Units])
+;
+
+[RelativeDistance]
+ ([ZapAll] *of the way)
+ ([ZapHalf] *of *the way)
+ ([ZapThird] of the way)
+ ([ZapTwoThird] of the way)
+ ([ZapOneQuarter] of the way)
+ ([ZapThreeQuarter] of the way)
+;
+
+[ZapAll]
+ (all)
+;
+
+[ZapHalf]
+ (halfway)
+ (one half)
+ (a half)
+ (half)
+;
+
+[ZapThird]
+ (one third)
+ (a third)
+;
+
+[ZapTwoThird]
+ (two third)
+ (two thirds)
+;
+
+[ZapOneQuarter]
+ (one quarters)
+ (one quarter)
+ (one forth)
+ (a quarters)
+ (a quarter)
+ (a forth)
+;
+
+
+[ZapThreeQuarter]
+ (three quarter)
+ (three quarters)
+ (three forth)
+ (three forths)
+;
+
+[HumanMoveCommand]
+# ([MoveVectorCardinal])
+ ([MoveVectorRelative])
+ ([MoveToGoal])
+;
+
+[CLYDEJOINBASHFUL]
+ (*clyde join bashful)
+;
+
+[BASHFULJOINCLYDE]
+ (*bashful join clyde)
+;
+
+#[MoveVectorCardinal]
+# (*[RobotName] MOVE *[CardinalDirection] [AbsoluteDistance])
+# (*[RobotName] MOVE [CardinalDirection])
+#
+#MOVE
+# (move)
+# (go)
+#;
+
+[MoveVectorRelative]
+ (*[RobotName] MOVE *[MoveDirection] [AbsoluteDistance])
+ (*[RobotName] MOVE *[AbsoluteDistance] [MoveDirection])
+
+MOVE
+ (move)
+ (go)
+ (drive)
+;
+
+[MoveToGoal]
+ (*[RobotName] MOVE *[RelativeDistance] PREP *[Side] [Goal])
+ (*[RobotName] MOVE [Home])
+
+MOVE
+ (move)
+ (go)
+ (drive)
+
+PREP
+ (toward)
+ (towards)
+ (to)
+ (down *to)
+ (down towards)
+ (up *to)
+ (up towards)
+;
+
+[Side]
+ (the=north=end=of)
+ (the=east=end=of)
+ (the=south=end=of)
+ (the=west=end=of)
+
+[Goal]
+ ([Home])
+ ([Xcoord] [Ycoord])
+;
+
+[Home]
+ (home)
+;
+
+[Xcoord]
+ (*negative [Number-20])
+;
+
+[Ycoord]
+ (*negative [Number-20])
+;
+
+[Units]
+ (meters)
+ (meter)
+# (feet)
+# (foot)
+# (yards)
+# (yard)
+;
+
+[HumanGoodbyeCommand]
+ (goodbye)
+ (bye bye)
+ (mission complete)
+ (that's it)
+;
+
+[HumanTurnCommand]
+ (TURN [TurnDirection])
+
+TURN
+ (turn)
+ (face)
+;
+
+[Number-20]
+ (zero)
+ (one)
+ (two)
+ (three)
+ (four)
+ (five)
+ (six)
+ (seven)
+ (eight)
+ (nine)
+ (ten)
+ (eleven)
+ (twelve)
+ (thirteen)
+ (fourteen)
+ (fifteen)
+ (sixteen)
+ (seventeen)
+ (eighteen)
+ (nineteen)
+ (twenty)
+;
+
+###################################################################
+# YES/NO grammar
+###################################################################
+
+[Yes]
+ (YES *MOD)
+ (STRONG_MOD)
+ (OKAY)
+ (WEAK_MOD)
+YES
+ (yes)
+ (yeah)
+ (yep)
+ (yup)
+MOD
+ (STRONG_MOD)
+ (WEAK_MOD)
+STRONG_MOD
+ (you betcha)
+#tk hack: interferes with "go forward" (*let's go for it)
+ (absolutely)
+ (definitely)
+ (OKAY OKAY)
+WEAK_MOD
+ (why not)
+ (i think so)
+ (i guess so)
+OKAY
+ (sure)
+ (of course)
+ (ok)
+ (okay)
+ (correct)
+ (fine)
+ (perfect)
+ (great)
+ (wonderful)
+ (acceptable)
+ (good *enough)
+ (right)
+ (alright)
+ (cool)
+;
+
+[No]
+ (no *MOD)
+ (*no absolutely not)
+ (nope)
+ (nah)
+ (no way)
+ (*no i DONT)
+ (*no i DONT think so)
+ (never mind)
+ (nevermind)
+ (*no not really)
+ (nowhere)
+ (negative)
+DONT
+ (don't)
+ (do not)
+MOD
+ (thanks)
+ (thank you)
+ (not really)
+ (i *really don't want to)
+ (it's not)
+ (i'm not)
+NO
+ (no)
+ (not)
+GOOD
+ (right)
+ (correct)
+ (good)
+ (okay)
+;
+
+
+###################################################################
+# CANCEL grammar
+###################################################################
+
+[Cancel]
+ (cancel *COMMAND)
+COMMAND
+ (*that command)
+ (that)
+;
\ No newline at end of file
Copied: TeamTalk/Resources/Grammar/TeamTalkTask.forms (from rev 574, TeamTalk/Resources/Grammar/zap2Task.forms)
===================================================================
--- TeamTalk/Resources/Grammar/TeamTalkTask.forms (rev 0)
+++ TeamTalk/Resources/Grammar/TeamTalkTask.forms 2007-04-06 20:09:41 UTC (rev 575)
@@ -0,0 +1,82 @@
+###################################################################
+#
+# ZAP Grammar
+#
+# Written by: June Sison
+#
+# This is the forms file corresponding to the phoenix grammar for
+# the Zap system
+#
+#
+# HISTORY -------------------------------------------------------
+#
+# [2005-09-21] (dbohus): added cancel
+# [2005-09-21] (tk): added yes/no
+# [2003-03-08] (sison): started working on this
+#
+###################################################################
+
+FUNCTION: Commands
+ NETS:
+ [HumanReportCommand]
+ [HumanLocationQuery]
+ [HumanMoveCommand]
+# [MoveVectorCardinal]
+ [MoveVectorRelative]
+ [MoveToGoal]
+ [HumanGoodbyeCommand]
+ [HumanTurnCommand]
+ [HumanHaltCommand]
+ [HumanFollowCommand]
+ [HumanPauseCommand]
+ [HumanContinueCommand]
+;
+
+FUNCTION: Features
+ NETS:
+ [AbsoluteDistance]
+ [TurnDirection]
+ [MoveDirection]
+ [Units]
+;
+
+FUNCTION: YesNo
+ NETS:
+# [Neither]
+ [Yes]
+ [No]
+;
+
+FUNCTION: Cancel
+ NETS:
+ [Cancel]
+;
+
+#FUNCTION: Queries
+# NETS:
+# [QueryProjector]
+# [QueryWhiteboard]
+# [QueryComputer]
+# [QueryNetworking]
+# [QueryLocation]
+# [QueryRoomSize]
+# [QueryRoomSizeSpec]
+# [QueryOtherRooms]
+# [QueryRoomDetails]
+#;
+
+#FUNCTION: Responses
+# NETS:
+# [Indifferent]
+# [Satisfied]
+# [SomewhatSatisfied]
+# [FirstOne]
+# [SecondOne]
+#;
+
+# these auxiliaries are defined in order to capture some parses like
+# next, this that, which o/w would parse as date-time
+#FUNCTION: Auxiliaries
+# NETS:
+# [__datetime_junk]
+#;
\ No newline at end of file
Modified: TeamTalk/Resources/Grammar/cmp.bat
===================================================================
--- TeamTalk/Resources/Grammar/cmp.bat 2007-04-05 20:17:36 UTC (rev 574)
+++ TeamTalk/Resources/Grammar/cmp.bat 2007-04-06 20:09:41 UTC (rev 575)
@@ -1,7 +1,7 @@
-'copy Generic.gra + zap2Task.gra zap2.gra
-copy zap2Task.gra zap2.gra
-'copy Generic.forms + zap2Task.forms forms
-copy zap2Task.forms forms
-perl mk_nets2.pl zap2.gra
-compile -g . -f zap2 > log
-concept_leaf -grammar zap2.net
+'copy Generic.gra + TeamTalkTask.gra TeamTalk.gra
+copy TeamTalkTask.gra TeamTalk.gra
+'copy Generic.forms + TeamTalkTask.forms forms
+copy TeamTalkTask.forms forms
+perl mk_nets2.pl TeamTalk.gra
+compile -g . -f TeamTalk > log
+concept_leaf -grammar TeamTalk.net
Deleted: TeamTalk/Resources/Grammar/zap2Task-template.gra
@@ Diff output truncated at 60000 characters. @@
More information about the TeamTalk-developers
mailing list