From: <sgv...@us...> - 2011-03-04 00:46:53
|
Revision: 251 http://simspark.svn.sourceforge.net/simspark/?rev=251&view=rev Author: sgvandijk Date: 2011-03-04 00:46:44 +0000 (Fri, 04 Mar 2011) Log Message: ----------- - Start of RCCMonitor (needs different name perhaps): gives agent state info Modified Paths: -------------- branches/rcctrainer/rcssserver3d/plugin/soccer/CMakeLists.txt branches/rcctrainer/rcssserver3d/plugin/soccer/agentstate/agentstate.cpp branches/rcctrainer/rcssserver3d/plugin/soccer/agentstate/agentstate.h branches/rcctrainer/rcssserver3d/plugin/soccer/export.cpp branches/rcctrainer/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.cpp Added Paths: ----------- branches/rcctrainer/rcssserver3d/plugin/soccer/rccmonitor/ branches/rcctrainer/rcssserver3d/plugin/soccer/rccmonitor/rccmonitor.cpp branches/rcctrainer/rcssserver3d/plugin/soccer/rccmonitor/rccmonitor.h branches/rcctrainer/rcssserver3d/plugin/soccer/rccmonitor/rccmonitor_c.cpp Modified: branches/rcctrainer/rcssserver3d/plugin/soccer/CMakeLists.txt =================================================================== --- branches/rcctrainer/rcssserver3d/plugin/soccer/CMakeLists.txt 2011-03-02 19:40:24 UTC (rev 250) +++ branches/rcctrainer/rcssserver3d/plugin/soccer/CMakeLists.txt 2011-03-04 00:46:44 UTC (rev 251) @@ -46,6 +46,7 @@ hmdp_effector/hmdpperceptor.h hmdp_effector/naospecific.h line/line.h + rccmonitor/rccmonitor.h ) set(soccer_LIB_SRCS @@ -120,6 +121,8 @@ hmdp_effector/naospecific.cpp line/line.cpp line/line_c.cpp + rccmonitor/rccmonitor.cpp + rccmonitor/rccmonitor_c.cpp ) include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${FREETYPE_INCLUDE_DIRS} Modified: branches/rcctrainer/rcssserver3d/plugin/soccer/agentstate/agentstate.cpp =================================================================== --- branches/rcctrainer/rcssserver3d/plugin/soccer/agentstate/agentstate.cpp 2011-03-02 19:40:24 UTC (rev 250) +++ branches/rcctrainer/rcssserver3d/plugin/soccer/agentstate/agentstate.cpp 2011-03-04 00:46:44 UTC (rev 251) @@ -154,9 +154,10 @@ } void -AgentState::AddSelfMessage(const string& msg) +AgentState::AddSelfMessage(const string& msg, float timeStamp) { mSelfMsg = msg; + mSelfMsgTimeStamp = timeStamp; mIfSelfMsg = true; } @@ -200,9 +201,9 @@ } bool -AgentState::GetSelfMessage(string& msg) +AgentState::GetSelfMessage(string& msg, bool check) { - if (! mIfSelfMsg) + if (check && ! mIfSelfMsg) { return false; } @@ -213,6 +214,12 @@ return true; } +float +AgentState::GetSelfMessageTimeStamp() +{ + return mSelfMsgTimeStamp; +} + void AgentState::UpdateHierarchyInternal() { Modified: branches/rcctrainer/rcssserver3d/plugin/soccer/agentstate/agentstate.h =================================================================== --- branches/rcctrainer/rcssserver3d/plugin/soccer/agentstate/agentstate.h 2011-03-02 19:40:24 UTC (rev 250) +++ branches/rcctrainer/rcssserver3d/plugin/soccer/agentstate/agentstate.h 2011-03-04 00:46:44 UTC (rev 251) @@ -85,12 +85,13 @@ /** Add a new message to the list */ void AddMessage(const std::string& msg, float direction, bool teamMate); - void AddSelfMessage(const std::string& msg); + void AddSelfMessage(const std::string& msg, float timeStamp); /** Get the first message from the list */ bool GetMessage(std::string& msg, float& direction, bool teamMate); - bool GetSelfMessage(std::string& msg); - + bool GetSelfMessage(std::string& msg, bool check = true); + float GetSelfMessageTimeStamp(); + bool IsSelected() const; void Select(bool s = true); void UnSelect(); @@ -111,6 +112,9 @@ /** self message */ std::string mSelfMsg; + /** time stamp of self message */ + float mSelfMsgTimeStamp; + /** team-mate's message */ std::string mMateMsg; float mMateMsgDir; Modified: branches/rcctrainer/rcssserver3d/plugin/soccer/export.cpp =================================================================== --- branches/rcctrainer/rcssserver3d/plugin/soccer/export.cpp 2011-03-02 19:40:24 UTC (rev 250) +++ branches/rcctrainer/rcssserver3d/plugin/soccer/export.cpp 2011-03-04 00:46:44 UTC (rev 251) @@ -54,6 +54,7 @@ #include "hmdp_effector/hmdpeffector.h" #include "hmdp_effector/hmdpperceptor.h" #include "line/line.h" +#include "rccmonitor/rccmonitor.h" ZEITGEIST_EXPORT_BEGIN() ZEITGEIST_EXPORT(SoccerControlAspect); @@ -90,5 +91,6 @@ ZEITGEIST_EXPORT(HMDPPerceptor); ZEITGEIST_EXPORT(HMDPEffector); ZEITGEIST_EXPORT(Line); + ZEITGEIST_EXPORT(RCCMonitor); ZEITGEIST_EXPORT_END() Added: branches/rcctrainer/rcssserver3d/plugin/soccer/rccmonitor/rccmonitor.cpp =================================================================== --- branches/rcctrainer/rcssserver3d/plugin/soccer/rccmonitor/rccmonitor.cpp (rev 0) +++ branches/rcctrainer/rcssserver3d/plugin/soccer/rccmonitor/rccmonitor.cpp 2011-03-04 00:46:44 UTC (rev 251) @@ -0,0 +1,476 @@ + +/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- + + this file is part of rcssserver3D + Fri May 9 2003 + Copyright (C) 2002,2003 Koblenz University + Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group + $Id: RCCMonitor.cpp 246 2011-02-18 18:44:14Z sgvandijk $ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#include "rccmonitor.h" +#include <zeitgeist/logserver/logserver.h> +#include <kerosin/sceneserver/singlematnode.h> +#include <kerosin/materialserver/material.h> +#include <oxygen/monitorserver/monitorcmdparser.h> +#include <oxygen/sceneserver/sceneserver.h> +#include <sstream> + +using namespace kerosin; +using namespace oxygen; +using namespace zeitgeist; +using namespace boost; +using namespace salt; +using namespace std; + +RCCMonitor::RCCMonitor() : oxygen::MonitorSystem() +{ + mFullState = true; +} + +RCCMonitor::~RCCMonitor() +{ +} + +void RCCMonitor::ClearNodeCache() +{ + mNodeCache.clear(); +} + +void RCCMonitor::UpdateCached() +{ + MonitorSystem::UpdateCached(); + ClearNodeCache(); +} + +void RCCMonitor::OnLink() +{ + // setup SceneServer reference + mSceneServer = shared_dynamic_cast<SceneServer> + (GetCore()->Get("/sys/server/scene")); + + if (mSceneServer.get() == 0) + { + GetLog()->Error() + << "(RCCMonitor) ERROR: SceneServer not found\n"; + } + +} + +void RCCMonitor::OnUnlink() +{ + mSceneServer.reset(); + mActiveScene.reset(); + ClearNodeCache(); +} + +void RCCMonitor::ParseMonitorMessage(const std::string& data) +{ + // pass the received string on to all installed CommandParsers + TLeafList items; + ListChildrenSupportingClass<MonitorCmdParser>(items); + + for ( + TLeafList::iterator iter = items.begin(); + iter != items.end(); + ++iter + ) + { + shared_static_cast<MonitorCmdParser>(*iter) + ->ParseMonitorMessage(data); + } +} + +string RCCMonitor::GetMonitorInfo(const PredicateList& pList) +{ + stringstream ss; + mFullState = false; + DescribeCustomPredicates(ss,pList); + DescribeActiveScene(ss); + + return ss.str(); +} + +string RCCMonitor::GetMonitorHeaderInfo(const PredicateList& pList) +{ + stringstream ss; + mFullState = true; + ClearNodeCache(); + DescribeCustomPredicates(ss,pList); + DescribeActiveScene(ss); + + return ss.str(); +} + +void RCCMonitor::DescribeCustomPredicates(stringstream& ss,const PredicateList& pList) +{ + ss << "("; + + for ( + PredicateList::TList::const_iterator iter = pList.begin(); + iter != pList.end(); + ++iter + ) + { + const Predicate& pred = (*iter); + + ss << "("; + ss << pred.name; + + const ParameterList& paramList = pred.parameter; + ParameterList::TVector::const_iterator pIter = paramList.begin(); + + std::string param; + while ( + (pIter != paramList.end()) && + (paramList.AdvanceValue(pIter, param)) + ) + { + ss << " "; + ss << param; + } + + ss << ")"; + } + + ss << ")"; +} + +void RCCMonitor::DescribeBaseNode(stringstream& ss) +{ + if (mFullState) + { + ss << "(nd BN"; + } else + { + ss << "(nd"; + } +} + +void RCCMonitor::DescribeLight(stringstream& ss, boost::shared_ptr<Light> light) +{ + if (! mFullState) + { + return DescribeBaseNode(ss); + } + + ss << "(nd Light "; + + const RGBA& diff = light->GetDiffuse(); + ss << "(setDiffuse " << diff.r() << " " << diff.g() << " " + << diff.b() << " " << diff.a() << ") "; + + const RGBA& amb = light->GetAmbient(); + ss << "(setAmbient " << amb.r() << " " << amb.g() << " " + << amb.b() << " " << amb.a() << ") "; + + const RGBA& spec = light->GetSpecular(); + ss << "(setSpecular " << spec.r() << " " << spec.g() << " " + << spec.b() << " " << spec.a() << ")"; +} + +void RCCMonitor::DescribeTransform(stringstream& ss, NodeCache& entry, boost::shared_ptr<Transform> transform) +{ + if (mFullState) + { + ss << "(nd TRF"; + } else + { + ss << "(nd"; + } + + // include transform data only for fullstate or a modified + // transform node + const float precision = 0.005f; + const Matrix& mat = transform->GetLocalTransform(); + + bool update = false; + + if (mFullState) + { + update = true; + } else + { + const salt::Matrix& old = entry.transform; + + for (int i=0;i<16;++i) + { + const float d = fabs(old.m[i] - mat.m[i]); + + if (d > precision) + { + update = true; + break; + } + } + } + + if (update) + { + ss << " (SLT"; + + for (int i=0;i<16;++i) + { + ss << " " << mat.m[i]; + } + + ss << ")"; + + // update cache + entry.transform = mat; + } +} + +void RCCMonitor::DescribeMesh(stringstream& ss, boost::shared_ptr<StaticMesh> mesh) +{ + boost::shared_ptr<SingleMatNode> singleMat = + shared_dynamic_cast<SingleMatNode>(mesh); + + if (singleMat.get() != 0) + { + ss << "(nd SMN"; + } else + { + ss << "(nd StaticMesh"; + } + + if (mFullState || mesh->VisibleToggled()) + if (mesh->IsVisible()) + ss << " (setVisible 1)"; + else + ss << " (setVisible 0)"; + + if (! mFullState) + return; + + if (mesh->IsTransparent()) + { + ss << " (setTransparent)"; + } + + ss << " (load " << mesh->GetMeshName(); + + const ParameterList& params = mesh->GetMeshParameter(); + for ( + ParameterList::TVector::const_iterator iter = params.begin(); + iter != params.end(); + ++iter + ) + { + string str; + params.GetValue(iter,str); + ss << " " << str; + } + + ss << ")"; + + const Vector3f& scale = mesh->GetScale(); + + ss << " (sSc " + << scale[0] << " " + << scale[1] << " " + << scale[2] << ")"; + + if (singleMat.get() != 0) + { + boost::shared_ptr<Material> mat = singleMat->GetMaterial(); + if (mat.get() != 0) + { + ss << " (sMat " << mat->GetName() << ")"; + } + } + else{ + std::vector<std::string> mats = mesh->GetMaterialNames(); + if ( !mats.empty() ){ + ss<<"(resetMaterials"; + for(std::vector<std::string>::const_iterator iter = mats.begin(); + mats.end() != iter; ++iter){ + ss<<' '<<*iter; + } + ss<<')'; + } + } +} + +void RCCMonitor::DescribeAgentState(stringstream& ss, NodeCache& entry, boost::shared_ptr<AgentState> agentstate) +{ + if (mFullState) + { + ss << "(nd AS "; + } + else + { + ss << "(nd "; + } + + int t = agentstate->GetTeamIndex(); + int u = agentstate->GetUniformNumber(); + + if (mFullState || entry.ints["team"] != t || entry.ints["unum"] != u) + { + ss << "(team " << (t == TI_LEFT ? "Left" : t == TI_RIGHT ? "Right" : "None") << ")" + << "(unum " << u << ")"; + entry.ints["team"] = t; + entry.ints["unum"] = u; + } + + string msg; + agentstate->GetSelfMessage(msg, false); + + if (msg != "" && agentstate->GetSelfMessageTimeStamp() != entry.floats["say"]) + { + ss << "(say " << msg << ")"; + entry.floats["say"] = agentstate->GetSelfMessageTimeStamp(); + } +} + +RCCMonitor::NodeCache* RCCMonitor::LookupNode(boost::shared_ptr<BaseNode> node) +{ + if (node.get() == 0) + { + assert(false); + return 0; + } + + TNodeCacheMap::iterator iter = mNodeCache.find(node); + if (iter != mNodeCache.end()) + { + return &((*iter).second); + } + + boost::shared_ptr<Transform> transform + = shared_dynamic_cast<Transform>(node); + + if (transform.get() != 0) + { + mNodeCache[node] + = NodeCache(NT_TRANSFORM, transform->GetLocalTransform()); + + return &(mNodeCache[node]); + } + + boost::shared_ptr<StaticMesh> mesh + = shared_dynamic_cast<StaticMesh>(node); + if (mesh.get() != 0) + { + mNodeCache[node] = NodeCache(NT_STATICMESH); + return &(mNodeCache[node]); + } + + boost::shared_ptr<Light> light + = shared_dynamic_cast<Light>(node); + if (light.get() != 0) + { + mNodeCache[node] = NodeCache(NT_LIGHT); + return &(mNodeCache[node]); + } + + boost::shared_ptr<AgentState> agentstate + = shared_dynamic_cast<AgentState>(node); + if (agentstate.get() != 0) + { + mNodeCache[node] = NodeCache(NT_AGENTSTATE); + return &(mNodeCache[node]); + } + + // treat every other node type as a BaseNode + mNodeCache[node] = NodeCache(NT_BASE); + + return &(mNodeCache[node]); +} + +bool RCCMonitor::DescribeNode(stringstream& ss, boost::shared_ptr<BaseNode> node) +{ + NodeCache* entry = LookupNode(node); + if (entry == 0) + { + // skip node + assert(false); + return false; + } + + switch (entry->type) + { + default: + assert(false); + // fall through + + case NT_BASE: + // skip node + return false; + + case NT_TRANSFORM: + DescribeTransform + (ss, (*entry), shared_static_cast<Transform>(node)); + return true; + + case NT_STATICMESH: + DescribeMesh + (ss, shared_static_cast<StaticMesh>(node)); + return true; + + case NT_LIGHT: + DescribeLight + (ss, shared_static_cast<Light>(node)); + return true; + + case NT_AGENTSTATE: + DescribeAgentState + (ss, (*entry), shared_static_cast<AgentState>(node)); + return true; + } +} + +void RCCMonitor::DescribeActiveScene(stringstream& ss) +{ + if (mSceneServer.get() == 0) + { + return; + } + + mActiveScene = mSceneServer->GetActiveScene(); + + if (mActiveScene.get() != 0) + { + if (mFullState) + { + ss << "(RSG 0 1)"; + } else + { + ss << "(RDS 0 1)"; + } + + ss << "("; + DescribeScene(ss,mActiveScene); + ss << ")"; + } +} + +void RCCMonitor::DescribeScene(stringstream& ss, boost::shared_ptr<BaseNode> node) +{ + bool closeParen = DescribeNode(ss, node); + + TLeafList baseNodes = node->GetBaseNodeChildren(); + for (TLeafList::iterator i = baseNodes.begin(); i!= baseNodes.end(); ++i) + { + boost::shared_ptr<BaseNode> baseNode = shared_dynamic_cast<BaseNode>(*i); + DescribeScene(ss,baseNode); + } + + if (closeParen) + { + ss << ")"; + } +} Added: branches/rcctrainer/rcssserver3d/plugin/soccer/rccmonitor/rccmonitor.h =================================================================== --- branches/rcctrainer/rcssserver3d/plugin/soccer/rccmonitor/rccmonitor.h (rev 0) +++ branches/rcctrainer/rcssserver3d/plugin/soccer/rccmonitor/rccmonitor.h 2011-03-04 00:46:44 UTC (rev 251) @@ -0,0 +1,159 @@ +/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- + + this file is part of rcssserver3D + Fri May 9 2003 + Copyright (C) 2002,2003 Koblenz University + Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group + $Id: sparkmonitor.h 3 2008-11-21 02:38:08Z hedayat $ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#ifndef RCCMONITOR_H__ +#define RCCMONITOR_H__ + +#include <oxygen/monitorserver/monitorsystem.h> +#include <oxygen/sceneserver/sceneserver.h> +#include <oxygen/sceneserver/scene.h> +#include <oxygen/sceneserver/transform.h> +#include <kerosin/sceneserver/staticmesh.h> +#include <kerosin/sceneserver/light.h> +#include <oxygen/physicsserver/body.h> +#include <agentstate/agentstate.h> + +class RCCMonitor : public oxygen::MonitorSystem +{ +public: + enum ENodeType + { + NT_BASE = 0, + NT_TRANSFORM, + NT_STATICMESH, + NT_LIGHT, + NT_AGENTSTATE + }; + + struct NodeCache + { + public: + ENodeType type; + + /** the last local transform matrix sent to the client */ + salt::Matrix transform; + + /** the last values of int types sent to the client */ + std::map<std::string, int> ints; + + /** the last values of int types sent to the client */ + std::map<std::string, float> floats; + + /** the last values of string types sent to the client */ + std::map<std::string, std::string> strings; + + public: + NodeCache(ENodeType nt = NT_BASE) + : type(nt) + { + } + + NodeCache(ENodeType nt, const salt::Matrix& t) + : type(nt), transform(t) + { + } + }; + + typedef std::map<boost::shared_ptr<oxygen::BaseNode>, NodeCache> TNodeCacheMap; + +public: + RCCMonitor(); + virtual ~RCCMonitor(); + + /** If a monitor sends information to the world model, this + * function is called to process it. + * @param data data sent from monitor to monitorsystem via SPADES. + */ + void ParseMonitorMessage(const std::string& data); + + /** This function will be called periodically to get information + * about the current state of the world. + * \param items holds a list of additional name value pairs. These + * predicates are collected from MonitorItem objects registered to + * the MonitorServer. The monitor should transfer them to the + * client if possible. + */ + virtual std::string GetMonitorInfo(const oxygen::PredicateList& pList); + + /** This function is called once for every MonitorSystem each time + * a new client connects. It should return any header/setup + * information that is needed. + * \param items holds a list of additional name value + * pairs. These predicates are collected from MonitorItem objects + * registered to the MonitorServer. The monitor should transfer + * them to the client if possible. + */ + virtual std::string GetMonitorHeaderInfo(const oxygen::PredicateList& pList); + + /** update variables from a script */ + virtual void UpdateCached(); + +protected: + virtual void OnLink(); + virtual void OnUnlink(); + + void ClearNodeCache(); + + /** This function looks the cached node entry in the node + cache. The entry is added to the cache if it does not exist + */ + NodeCache* LookupNode(boost::shared_ptr<oxygen::BaseNode> node); + + void DescribeCustomPredicates(std::stringstream& ss,const oxygen::PredicateList& pList); + void DescribeActiveScene(std::stringstream& ss); + void DescribeScene(std::stringstream& ss, + boost::shared_ptr<oxygen::BaseNode> node); + + /** This function writes the s-expression for the given node to + the given strinstream, omitting the closing parentheses. It + returns false if the node is skipped and no description is + created. Skipped nodes are invisible scene graph nodes. + */ + bool DescribeNode(std::stringstream& ss, + boost::shared_ptr<oxygen::BaseNode> node); + void DescribeBaseNode(std::stringstream& ss); + void DescribeTransform(std::stringstream& ss, NodeCache& entry, + boost::shared_ptr<oxygen::Transform> transform); + void DescribeMesh(std::stringstream& ss, + boost::shared_ptr<kerosin::StaticMesh> mesh); + void DescribeLight(std::stringstream& ss, + boost::shared_ptr<kerosin::Light> light); + void DescribeAgentState(std::stringstream& ss, NodeCache& entry, + boost::shared_ptr<AgentState>); + +protected: + /** cached reference to the SceneServer */ + boost::shared_ptr<oxygen::SceneServer> mSceneServer; + + /** cached reference to the current active scene */ + boost::shared_ptr<oxygen::Scene> mActiveScene; + + /** true, if the full state is generated */ + bool mFullState; + + /** cached node type and state */ + TNodeCacheMap mNodeCache; +}; + +DECLARE_CLASS(RCCMonitor); + +#endif // RCCMONITOR_H__ + Added: branches/rcctrainer/rcssserver3d/plugin/soccer/rccmonitor/rccmonitor_c.cpp =================================================================== --- branches/rcctrainer/rcssserver3d/plugin/soccer/rccmonitor/rccmonitor_c.cpp (rev 0) +++ branches/rcctrainer/rcssserver3d/plugin/soccer/rccmonitor/rccmonitor_c.cpp 2011-03-04 00:46:44 UTC (rev 251) @@ -0,0 +1,29 @@ +/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- + + this file is part of rcssserver3D + Fri May 9 2003 + Copyright (C) 2002,2003 Koblenz University + Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group + $Id: sparkmonitor_c.cpp 3 2008-11-21 02:38:08Z hedayat $ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#include "rccmonitor.h" + +void +CLASS(RCCMonitor)::DefineClass() +{ + DEFINE_BASECLASS(oxygen/BaseParser); +} + Modified: branches/rcctrainer/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.cpp =================================================================== --- branches/rcctrainer/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.cpp 2011-03-02 19:40:24 UTC (rev 250) +++ branches/rcctrainer/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.cpp 2011-03-04 00:46:44 UTC (rev 251) @@ -1300,7 +1300,7 @@ { if ( (*it)->GetUniformNumber() == number) { - (*it)->AddSelfMessage(message); + (*it)->AddSelfMessage(message, mGameState->GetTime()); continue; } SoccerBase::GetTransformParent(*(*it), transform_parent); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |