Gazebo Sim

API Reference

9.0.0
StatesImpl.hh
Go to the documentation of this file.
1/*
2 * Copyright (C) 2021 Open Source Robotics Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18/*
19 * \author Nick Lamprianidis <nlamprian@gmail.com>
20 * \date January 2021
21 */
22
23#include <memory>
24#include <string>
25
26#include "../ElevatorStateMachine.hh"
27
28#include <gz/common/Console.hh>
29
30namespace gz
31{
32namespace sim
33{
34// Inline bracket to help doxygen filtering
35inline namespace GZ_SIM_VERSION_NAMESPACE {
36namespace systems
37{
39struct ElevatorStateMachineDef::IdleState : state<IdleState>
40{
42 public: template <typename Event, typename FSM>
43 void on_enter(const Event &, FSM &)
44 {
45 gzmsg << "The elevator is idling" << std::endl;
46 }
47};
48
50template <typename E>
51struct ElevatorStateMachineDef::DoorState : state<DoorState<E>>
52{
58 public: DoorState(double _posEps = 2e-2, double _velEps = 1e-2)
59 : posEps(_posEps), velEps(_velEps)
60 {
61 }
62
64 public: virtual ~DoorState()
65 {
66 }
67
71 public: template <typename Event, typename FSM>
72 void on_enter(const Event &, FSM &_fsm)
73 {
74 const auto &data = _fsm.dataPtr;
75 int32_t floorTarget = data->system->state;
76 gzmsg << "The elevator is " << this->Report(data) << std::endl;
77
78 double jointTarget = this->JointTarget(data, floorTarget);
79 data->SendCmd(data->system->doorJointCmdPubs[floorTarget], jointTarget);
80 this->triggerEvent = [&_fsm] { _fsm.process_event(E()); };
81 data->system->SetDoorMonitor(
82 floorTarget, jointTarget, this->posEps, this->velEps,
83 std::bind(&DoorState::OnJointTargetReached, this));
84 }
85
89 private: virtual std::string Report(
91
96 private: virtual double JointTarget(
98 int32_t _floorTarget) const = 0;
99
101 private: void OnJointTargetReached()
102 {
103 this->triggerEvent();
104 }
105
107 private: double posEps;
108
110 private: double velEps;
111
113 private: std::function<void()> triggerEvent;
114};
115
117struct ElevatorStateMachineDef::OpenDoorState : DoorState<events::DoorOpen>
118{
120 public: using deferred_events = type_tuple<events::EnqueueNewTarget>;
121
123 public: OpenDoorState() = default;
124
125 // Documentation inherited
126 private: virtual std::string Report(
127 const std::unique_ptr<ElevatorStateMachinePrivate> &_data) const override
128 {
129 return "opening door " + std::to_string(_data->system->state);
130 }
131
132 // Documentation inherited
133 private: virtual double JointTarget(
135 int32_t _floorTarget) const override
136 {
137 return _data->system->doorTargets[_floorTarget];
138 }
139};
140
142struct ElevatorStateMachineDef::CloseDoorState : DoorState<events::DoorClosed>
143{
145 public: CloseDoorState() = default;
146
147 // Documentation inherited
148 private: virtual std::string Report(
149 const std::unique_ptr<ElevatorStateMachinePrivate> &_data) const override
150 {
151 return "closing door " + std::to_string(_data->system->state);
152 }
153
154 // Documentation inherited
155 private: virtual double JointTarget(
157 int32_t /*_floorTarget*/) const override
158 {
159 return 0.0;
160 }
161};
162
164struct ElevatorStateMachineDef::WaitState : state<WaitState>
165{
167 public: using deferred_events = type_tuple<events::EnqueueNewTarget>;
168
171 public: template <typename Event, typename FSM>
172 void on_enter(const Event &, FSM &_fsm)
173 {
174 const auto &data = _fsm.dataPtr;
175 gzmsg << "The elevator is waiting to close door " << data->system->state
176 << std::endl;
177
178 this->triggerEvent = [&_fsm] { _fsm.process_event(events::Timeout()); };
179 data->system->StartDoorTimer(data->system->state,
180 std::bind(&WaitState::OnTimeout, this));
181 }
182
184 private: void OnTimeout()
185 {
186 this->triggerEvent();
187 }
188
190 private: std::function<void()> triggerEvent;
191};
192
194struct ElevatorStateMachineDef::MoveCabinState : state<MoveCabinState>
195{
197 public: using deferred_events = type_tuple<events::EnqueueNewTarget>;
198
204 public: MoveCabinState(double _posEps = 15e-2, double _velEps = 1e-2)
205 : posEps(_posEps), velEps(_velEps)
206 {
207 }
208
212 public: template <typename Event, typename FSM>
213 void on_enter(const Event &, FSM &_fsm)
214 {
215 const auto &data = _fsm.dataPtr;
216 int32_t floorTarget = data->targets.front();
217 gzmsg << "The elevator is moving the cabin [ " << data->system->state
218 << " -> " << floorTarget << " ]" << std::endl;
219
220 double jointTarget = data->system->cabinTargets[floorTarget];
221 data->SendCmd(data->system->cabinJointCmdPub, jointTarget);
222 this->triggerEvent = [&_fsm] {
223 _fsm.process_event(events::CabinAtTarget());
224 };
225 data->system->SetCabinMonitor(
226 floorTarget, jointTarget, this->posEps, this->velEps,
227 std::bind(&MoveCabinState::OnJointTargetReached, this));
228 }
229
231 private: void OnJointTargetReached()
232 {
233 this->triggerEvent();
234 }
235
237 private: double posEps;
238
240 private: double velEps;
241
243 private: std::function<void()> triggerEvent;
244};
245
246} // namespace systems
247} // namespace GZ_SIM_VERSION_NAMESPACE
248} // namespace sim
249} // namespace gz