Main Page · Modules · All Classes · Class Hierarchy
MAComplexIndicators.cpp
1 /*
2  * This file is part of the AiBO+ project
3  *
4  * Copyright (C) 2005-2016 Csaba Kertész (csaba.kertesz@gmail.com)
5  *
6  * AiBO+ is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * AiBO+ is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
19  *
20  */
21 
22 #include "MAComplexIndicators.hpp"
23 
24 #include "MAAudio.hpp"
25 #include "MABodyMotion.hpp"
26 #include "MAGoals.hpp"
27 #include "MAHead.hpp"
28 #include "MALeg.hpp"
29 #include "MARobotState.hpp"
30 #include "MATorso.hpp"
31 #include "MATypeRanges.hpp"
32 
34  WalkPeriod(2400, 1400, 3200),
35  ElapsedForwardWalkTime(0, 0, 100000),
36  ElapsedBackwardWalkTime(0, 0, 100000),
37  ElapsedLeftTurnTime(0, 0, 20700),
38  ElapsedRightTurnTime(0, 0, 20700),
39  AbyssWhileLying(-1, -1, 1),
40  LeftMicrophoneDominance(0, 0, 255), RightMicrophoneDominance(0, 0, 255),
41  MicrophoneChannelsBalance(0, 0, 255),
42  NearObjectForwardFactor(0, 0, 2000),
43  AbyssWhileWalkingFactor(0, 0, 3000),
44  BodyOutOfWalkingRangeFactor(0, 0, 500),
45  OverloadDangerWhileSittingFactor(0, 0, 3000),
46  WalkSpeedAccelerationStart(-1)
47 {
48  AbyssWhileWalking.SetMinMax(MA::StandardRangeMin, MA::StandardRangeMax);
49  NearObjectForward.SetMinMax(MA::StandardRangeMin, MA::StandardRangeMax);
50  BodyOutOfWalkingRange.SetMinMax(MA::StandardRangeMin, MA::StandardRangeMax);
51  OverloadDangerWhileSitting.SetMinMax(MA::StandardRangeMin, MA::StandardRangeMax);
52 }
53 
54 
56 {
59 }
60 
61 
63 {
64  IsLyingPosture = state.LegLF->IsLyingPosition &&
65  state.LegLH->IsLyingPosition &&
66  state.LegRF->IsLyingPosition &&
67  state.LegRH->IsLyingPosition;
68  IsStandingPosture = state.LegLF->IsStandingPosition &&
69  state.LegLH->IsStandingPosition &&
70  state.LegRF->IsStandingPosition &&
71  state.LegRH->IsStandingPosition;
72  IsSittingPosture = state.LegLF->IsSittingPosition &&
73  state.LegLH->IsSittingPosition &&
74  state.LegRF->IsSittingPosition &&
75  state.LegRH->IsSittingPosition;
76  GenerateWalkPeriod(state);
77  GenerateNearObjectForward(state);
78  GenerateAbyssWhileWalking(state);
79  GenerateAbyssWhileLying(state);
80  GenerateBodyOutOfWalkingRange(state);
81  GenerateOverloadDangerWhileSitting(state);
82  GenerateListenWithEars(state);
83  GenerateMicrophoneChannelDominances(state);
84 }
85 
86 
87 void MAComplexIndicators::GenerateWalkPeriod(MARobotState& state)
88 {
91  {
92  WalkSpeedAccelerationStart = -1;
93  WalkPeriod = 2400;
94  } else
96  {
97  // Increase the forward walk speed by lowering the walk period to 2000
98  if (ElapsedForwardWalkTime > 0 && state.BodyMotion->Floor.Surface != MA::UnknownFloor &&
99  state.BodyMotion->Floor.Surface != MA::Carpet)
100  {
101  if (WalkSpeedAccelerationStart == -1)
102  {
103  WalkSpeedAccelerationStart = ElapsedForwardWalkTime;
104  }
105  if (ElapsedForwardWalkTime-WalkSpeedAccelerationStart < 4800)
106  {
107  WalkPeriod = 2400-(ElapsedForwardWalkTime-WalkSpeedAccelerationStart) / 12;
108  } else {
109  WalkPeriod = 2000;
110  }
111  } else
112  {
113  WalkSpeedAccelerationStart = -1;
114  if (WalkPeriod > 2350)
115  WalkPeriod = 2400;
116  }
117  } else // -V705 (PVS Studio suppression)
118  // Adjust the walk period from 2800 to 2400 when the walk is beginning instead of
119  // a sudden start with the same speed.
120  if (ElapsedForwardWalkTime > 0)
121  {
123  WalkSpeedAccelerationStart = -1;
124  } else
125  if (ElapsedBackwardWalkTime > 0)
126  {
128  WalkSpeedAccelerationStart = -1;
129  }
130 }
131 
132 
133 void MAComplexIndicators::GenerateNearObjectForward(MARobotState& state)
134 {
135  if (state.Torso->NearIR <= 15 && state.BodyMotion->IsBodyRollInWalkRange())
136  {
137  // Obstacle detection can be reached in 500 ms
138  NearObjectForwardFactor += state.Torso->CycleTime*4;
139  } else {
140  NearObjectForwardFactor -= state.Torso->CycleTime;
141  }
142  NearObjectForward = NearObjectForwardFactor.GetScaledValue();
143 }
144 
145 
146 void MAComplexIndicators::GenerateAbyssWhileWalking(MARobotState& state)
147 {
148  if (state.Torso->ChestIR > 65 && state.BodyMotion->IsBodyRollInWalkRange() &&
149  // The activation starts while walking, but it is kept after the forward walk is stopped
151  {
152  // Abyss detection can be reached in 500 ms
153  AbyssWhileWalkingFactor += state.Torso->CycleTime*6;
154  } else {
155  AbyssWhileWalkingFactor -= state.Torso->CycleTime;
156  }
157  AbyssWhileWalking = AbyssWhileWalkingFactor.GetScaledValue();
158 }
159 
160 
161 void MAComplexIndicators::GenerateAbyssWhileLying(MARobotState& state)
162 {
163  if (state.BodyMotion->Flying > 90 || state.BodyMotion->UpsideDown > 80 ||
166  {
167  AbyssWhileLying = -1;
168  return;
169  }
170 }
171 
172 
173 void MAComplexIndicators::GenerateBodyOutOfWalkingRange(MARobotState& state)
174 {
175  if (!state.BodyMotion->IsBodyRollInWalkRange())
176  {
177  // The robot body can be out of walking range after 500 ms
178  BodyOutOfWalkingRangeFactor += state.Torso->CycleTime;
179  } else {
180  BodyOutOfWalkingRangeFactor -= state.Torso->CycleTime;
181  }
182  BodyOutOfWalkingRange = BodyOutOfWalkingRangeFactor.GetScaledValue();
183 }
184 
185 
186 void MAComplexIndicators::GenerateOverloadDangerWhileSitting(MARobotState& state)
187 {
188  int Hits = 0;
189 
190  Hits += state.LegLF->Force1 <= MA::ForeLegForce1SittingLimit;
191  Hits += (state.LegLF->Force1 <= MA::ForeLegForce1SittingEmergencyLimit)*3;
192  Hits += state.LegLF->Force3 <= MA::ForeLegForce3SittingLimit;
193  Hits += state.LegRF->Force1 <= MA::ForeLegForce1SittingLimit;
194  Hits += (state.LegRF->Force1 <= MA::ForeLegForce1SittingEmergencyLimit)*3;
195  Hits += state.LegRF->Force3 <= MA::ForeLegForce3SittingLimit;
196  if (Hits >= 3)
197  {
198  // The front legs are overloaded while sitting after 1500 ms
199  OverloadDangerWhileSittingFactor += state.Torso->CycleTime;
200  } else {
201  OverloadDangerWhileSittingFactor -= state.Torso->CycleTime;
202  }
203  OverloadDangerWhileSitting = OverloadDangerWhileSittingFactor.GetScaledValue();
204 }
205 
206 
207 void MAComplexIndicators::GenerateListenWithEars(MARobotState& state)
208 {
209  bool SelfNoises = false;
210 
211  SelfNoises = SelfNoises || (state.Audio->RemainingPlaybackTime > 0 && state.Audio->SpeakerVolume > 0);
212  SelfNoises = SelfNoises || state.LegLF->InMotion > 0 || state.LegLH->InMotion > 0;
213  SelfNoises = SelfNoises || state.LegRF->InMotion > 0 || state.LegRH->InMotion > 0;
214  SelfNoises = SelfNoises || (state.Head->InMotion > 0 && !state.Goals->TurnHeadToLeft && !state.Goals->TurnHeadToRight);
215 
216  bool GoodPose = false;
217 
218  GoodPose = GoodPose || state.BodyMotion->Lying > 90;
219  GoodPose = GoodPose || state.BodyMotion->Sitting > 90;
220  GoodPose = GoodPose || IsStandingPosture > 0;
221 
222  if (!SelfNoises && GoodPose)
223  ListenWithEars = 1;
224  else
225  ListenWithEars = 0;
226 }
227 
228 
229 void MAComplexIndicators::GenerateMicrophoneChannelDominances(MARobotState& state)
230 {
231  const int MinPower = 2000;
232  const int LeftPower = state.Audio->LeftMicrophonePower;
233  const int RightPower = state.Audio->RightMicrophonePower;
234  const int BackgroundPower = state.Audio->BackgroundSoundPower;
235 
236  if (((LeftPower > MinPower && LeftPower > BackgroundPower*5) ||
237  (RightPower > MinPower && RightPower > BackgroundPower*5)) &&
238  MA::RobotState->ComplexIndicators->ListenWithEars == 1)
239  {
240  if ((float)LeftPower > (float)RightPower*1.05)
242  else
243  if ((float)LeftPower*1.05 < (float)RightPower)
245  else
247  }
248  // Similar to other indicators, the dominances are accumulated over time,
249  // but decreased at fixed rate.
253 }
MANum< int > BodyOutOfWalkingRange
The robot body is out of the walking range.
MAComplexIndicators()
Struct constructor.
MANum< int > ElapsedRightTurnTime
The current right turning time (in msec)
MANum< int > WalkPeriod
The walk period of the robot.
MANum< int > ListenWithEars
Whenever listening with ears.
virtual void SetMinMax(T min_value, T max_value)
Set the minimal and maximal values.
Definition: MANum.hpp:235
MANum< int > MicrophoneChannelsBalance
Counter for the balance of the microphone channels.
MANum< int > ElapsedBackwardWalkTime
The current backward walk time (in msec)
bool IsLocomotionActive() const
Check if the locomotion is active now.
MANum< int > OverloadDangerWhileSitting
Overload danger in the first legs while sitting.
MANum< int > AbyssWhileWalking
Abyss is before the dog while walking.
boost::scoped_ptr< MALeg > LegRH
LegRH.
MANum< int > ElapsedLeftTurnTime
The current left turning time (in msec)
virtual void UpdateRobotState(MARobotState &state) override
Update the robot state.
boost::scoped_ptr< MAGoals > Goals
Goals.
MANum< int > RightMicrophoneDominance
Counter for the dominance of the right microphone channel.
boost::scoped_ptr< MABodyMotion > BodyMotion
Body motion.
boost::scoped_ptr< MALeg > LegLF
LegLF.
Robot state updater base class.
MANum< int > LeftMicrophoneDominance
Counter for the dominance of the left microphone channel.
boost::scoped_ptr< MALeg > LegRF
LegRF.
MANum< int > ElapsedForwardWalkTime
The current forward walk time (in msec)
boost::scoped_ptr< MAAudio > Audio
Audio input/output.
boost::scoped_ptr< MATorso > Torso
Torso.
boost::scoped_ptr< MALeg > LegLH
LegLH.
Robot state.
T GetValueChange() const
The last value change difference.
Definition: MANum.hpp:287
boost::scoped_ptr< MAHead > Head
Head.