Simulable.cpp
Go to the documentation of this file.
1 /*+-------------------------------------------------------------------------+
2  | MultiVehicle simulator (libmvsim) |
3  | |
4  | Copyright (C) 2014-2020 Jose Luis Blanco Claraco |
5  | Copyright (C) 2017 Borys Tymchenko (Odessa Polytechnic University) |
6  | Distributed under 3-clause BSD License |
7  | See COPYING |
8  +-------------------------------------------------------------------------+ */
9 
11 #include <mvsim/Comms/Client.h>
12 #include <mvsim/Simulable.h>
14 #include <mvsim/World.h>
15 
16 #include "xml_utils.h"
17 
18 #if defined(MVSIM_HAS_ZMQ) && defined(MVSIM_HAS_PROTOBUF)
19 #include "TimeStampedPose.pb.h"
20 
21 #endif
22 
23 using namespace mvsim;
24 
26  [[maybe_unused]] const TSimulContext& context)
27 {
28  if (!m_b2d_body) return;
29 
30  // Pos:
31  m_b2d_body->SetTransform(b2Vec2(m_q.x, m_q.y), m_q.yaw);
32 
33  // Vel:
34  m_b2d_body->SetLinearVelocity(b2Vec2(m_dq.vx, m_dq.vy));
35  m_b2d_body->SetAngularVelocity(m_dq.omega);
36 }
37 
39  [[maybe_unused]] const TSimulContext& context)
40 {
41  if (!m_b2d_body) return;
42 
44 
45  // Pos:
46  const b2Vec2& pos = m_b2d_body->GetPosition();
47  const float32 angle = m_b2d_body->GetAngle();
48  m_q.x = pos(0);
49  m_q.y = pos(1);
50  m_q.yaw = angle;
51  // The rest (z,pitch,roll) will be always 0, unless other
52  // world-element modifies them! (e.g. elevation map)
53 
54  // Vel:
55  const b2Vec2& vel = m_b2d_body->GetLinearVelocity();
56  const float32 w = m_b2d_body->GetAngularVelocity();
57  m_dq.vx = vel(0);
58  m_dq.vy = vel(1);
59  m_dq.omega = w;
60 
61  // Instantaneous collision flag:
62  m_isInCollision = false;
63  if (b2ContactEdge* cl = m_b2d_body->GetContactList();
64  cl != nullptr && cl->contact != nullptr && cl->contact->IsTouching())
65  {
66  // We may store with which other bodies it's in collision...
67  m_isInCollision = true;
68  }
69  // Reseteable collision flag:
70  m_hadCollisionFlag = m_hadCollisionFlag || m_isInCollision;
71 
73 
74  // Optional publish to topics:
75  internalHandlePublish(context);
76 }
77 
79  [[maybe_unused]] const mrpt::math::TVector2D& force,
80  [[maybe_unused]] const mrpt::math::TPoint2D& applyPoint)
81 { /* default: do nothing*/
82 }
83 
85 {
86  std::shared_lock lck(m_q_mtx);
87 
88  mrpt::math::TTwist2D local_vel = m_dq;
89  local_vel.rotate(-m_q.yaw); // "-" means inverse pose
90  return local_vel;
91 }
92 
94 {
95  std::shared_lock lck(m_q_mtx);
96 
97  return {m_q.x, m_q.y, m_q.yaw};
98 }
99 
100 bool Simulable::parseSimulable(const rapidxml::xml_node<char>* node)
101 {
102  MRPT_START
103 
104  if (node == nullptr) return false;
105 
107  params["publish_pose_topic"] = TParamEntry("%s", &publishPoseTopic_);
108  params["publish_pose_period"] = TParamEntry("%lf", &publishPosePeriod_);
109 
110  const std::map<std::string, std::string> varValues = {{"NAME", m_name}};
111 
112  // Parse XML params:
113  parse_xmlnode_children_as_param(*node, params, varValues);
114 
115  return true;
116  MRPT_END
117 }
118 
119 void Simulable::internalHandlePublish(const TSimulContext& context)
120 {
121  std::shared_lock lck(m_q_mtx);
122 
123  MRPT_START
124  if (publishPoseTopic_.empty()) return;
125 
126  auto& client = context.world->commsClient();
127 
128  const double tNow = mrpt::Clock::toDouble(mrpt::Clock::now());
129  if (tNow < publishPoseLastTime_ + publishPosePeriod_) return;
130 
131  publishPoseLastTime_ = tNow;
132 
133  mvsim_msgs::TimeStampedPose msg;
134  msg.set_unixtimestamp(tNow);
135  msg.set_objectid(m_name);
136 
137  auto pose = msg.mutable_pose();
138  pose->set_x(m_q.x);
139  pose->set_y(m_q.y);
140  pose->set_z(.0);
141  pose->set_yaw(m_q.yaw);
142  pose->set_pitch(m_q.pitch);
143  pose->set_roll(m_q.roll);
144 
145  client.publishTopic(publishPoseTopic_, msg);
146 
147  MRPT_END
148 }
149 
151 {
152  MRPT_START
153 
154 #if defined(MVSIM_HAS_ZMQ) && defined(MVSIM_HAS_PROTOBUF)
155  // Topic:
156  if (!publishPoseTopic_.empty())
157  c.advertiseTopic<mvsim_msgs::TimeStampedPose>(publishPoseTopic_);
158 #endif
159 
160  MRPT_END
161 }
std::map< std::string, TParamEntry > TParameterDefinitions
bool IsTouching() const
Is this contact touching?
Definition: b2Contact.h:259
void parse_xmlnode_children_as_param(const rapidxml::xml_node< char > &xml_node, const TParameterDefinitions &params, const std::map< std::string, std::string > &variableNamesValues={}, const char *functionNameContext="")
Definition: xml_utils.cpp:179
const GLfloat * c
mrpt::poses::CPose2D getCPose2D() const
Alternative to getPose()
Definition: Simulable.cpp:93
GLubyte GLubyte GLubyte GLubyte w
mrpt::system::TTimeStamp now()
virtual void apply_force(const mrpt::math::TVector2D &force, const mrpt::math::TPoint2D &applyPoint=mrpt::math::TPoint2D(0, 0))
Definition: Simulable.cpp:78
A 2D column vector.
Definition: b2Math.h:52
b2Contact * contact
the contact
Definition: b2Contact.h:69
#define MRPT_END
mrpt::math::TTwist2D getVelocityLocal() const
Definition: Simulable.cpp:84
void rotate(const double ang)
virtual void registerOnServer(mvsim::Client &c)
Definition: Simulable.cpp:150
virtual void simul_post_timestep(const TSimulContext &context)
Definition: Simulable.cpp:38
#define MRPT_START
virtual void simul_pre_timestep(const TSimulContext &context)
Definition: Simulable.cpp:25
virtual void poses_mutex_unlock()=0
void advertiseTopic(const std::string &topicName)
Definition: Client.h:158
GLfloat * params
virtual void poses_mutex_lock()=0
GLdouble angle
float32 x
Definition: b2Math.h:139
std::string m_name
Definition: Simulable.h:118
mvsim::Client & commsClient()
Definition: World.h:247
float float32
Definition: b2Settings.h:35


mvsim
Author(s):
autogenerated on Fri May 7 2021 03:05:51