21 const std::shared_ptr<const IHexapodPostureValidator>& checker_ptr)
22 : checker_ptr_(checker_ptr), evaluator_(InitializeEvaluator()) {}
24std::tuple<GraphSearchResult, GraphSearchEvaluationValue, RobotStateNode>
40 Vector3 normalized_move_direction;
43 normalized_move_direction =
46 normalized_move_direction.
z = 0.0f;
47 normalized_move_direction = normalized_move_direction.
GetNormalized();
50 normalized_move_direction.
z = 0.0f;
51 normalized_move_direction = normalized_move_direction.
GetNormalized();
52 normalized_move_direction = normalized_move_direction.
GetLength() == 0.0f
54 : normalized_move_direction;
57 const float target_z_value = InitTargetZValue(
58 graph.
GetRootNode(), divided_map_state, normalized_move_direction);
64 int max_evaluation_value_index = -1;
83 candidate_evaluation_value.
value.at(kTagMoveForward) =
85 normalized_move_direction);
89 candidate_evaluation_value.
value.at(kTagLegRot) =
93 candidate_evaluation_value.
value.at(kTagZDiff) = GetZDiffEvaluationValue(
102 max_evaluation_value)) {
105 max_evaluation_value.
value[kTagZDiff]);
106 max_evaluation_value = candidate_evaluation_value;
107 max_evaluation_value_index = i;
112 if (graph.
GetGraphSize() <= max_evaluation_value_index) {
114 "最大評価値のインデックスが範囲外です."};
118 if (max_evaluation_value_index < 0) {
121 std::format(
"葉ノードが存在しません.最大深さ : {},動作 : {}", log_depth,
129 return {result, max_evaluation_value,
133std::tuple<GraphSearchResult, GraphSearchEvaluationValue, RobotStateNode>
135 const std::vector<GaitPatternGraphTree>& graph_vector,
137 int max_depth)
const {
139 std::tuple<GraphSearchResult, GraphSearchEvaluationValue, RobotStateNode>>
141 result_vector.resize(graph_vector.size());
143 for (
size_t i = 0; i < graph_vector.size(); i++) {
146 divided_map_state, max_depth);
152 int max_evaluation_value_index = -1;
154 for (
int i = 0; i < result_vector.size(); i++) {
155 const auto& [result, evaluation_value, _] = result_vector[i];
163 if (evaluator_.
LeftIsBetter(evaluation_value, max_evaluation_value)) {
165 max_evaluation_value = evaluation_value;
166 max_evaluation_value_index = i;
171 if (max_evaluation_value_index < 0 ||
172 result_vector.size() <= max_evaluation_value_index) {
174 "最大評価値のインデックスが範囲外です."};
178 return result_vector[max_evaluation_value_index];
187 GraphSearchEvaluator::EvaluationMethod leg_rot_method = {
188 .is_lower_better =
false,
192 GraphSearchEvaluator::EvaluationMethod z_diff_method = {
193 .is_lower_better =
true,
197 GraphSearchEvaluator ret({{kTagMoveForward, move_forward_method},
198 {kTagLegRot, leg_rot_method},
199 {kTagZDiff, z_diff_method}},
200 {kTagZDiff, kTagMoveForward, kTagLegRot});
205float GraphSearcherStraightMove::InitTargetZValue(
206 const RobotStateNode& node,
const DividedMapState& divided_map_state,
207 const Vector3& move_direction)
const {
208 const float move_length = 100.0f;
210 const Vector3 target_position = move_direction * move_length;
213 const float min_z = -150.0f;
214 const float max_z = 150.0f;
216 for (
int i = 0; i < div; i++) {
217 const float z = min_z + (max_z - min_z) /
static_cast<float>(div) *
218 static_cast<float>(i);
220 Vector3 pos = node.center_of_mass_global_coord;
221 pos += target_position;
224 RobotStateNode temp_node = node;
225 temp_node.ChangeGlobalCenterOfMass(pos,
false);
227 if (!checker_ptr_->IsBodyInterferingWithGround(temp_node,
228 divided_map_state)) {
229 return node.center_of_mass_global_coord.z + z;
233 return node.center_of_mass_global_coord.z;
236float GraphSearcherStraightMove::GetMoveForwardEvaluationValue(
237 const RobotStateNode& node,
const RobotStateNode& root_node,
238 const Vector3& normalized_move_direction)
const {
242 const Vector3 root_to_current =
243 node.center_of_mass_global_coord - root_node.center_of_mass_global_coord;
246 const float result = root_to_current.Dot(normalized_move_direction);
253float GraphSearcherStraightMove::GetLegRotEvaluationValue(
254 const RobotStateNode& node,
const RobotStateNode& root_node)
const {
260 (node.leg_pos[i].ProjectedXY() - root_node.leg_pos[i].ProjectedXY())
263 result += (node.leg_pos[i] - root_node.leg_pos[i]).GetLength();
272float GraphSearcherStraightMove::GetZDiffEvaluationValue(
273 const std::vector<float>& com_trajectory,
274 const float target_z_value)
const {
275 float result = abs(com_trajectory.back() - target_z_value);
277 if (com_trajectory.size() == 3) {
278 if ((com_trajectory[0] - com_trajectory[1]) *
279 (com_trajectory[0] - com_trajectory[2]) <=
281 result += abs(com_trajectory[0] - com_trajectory[1]);
RobotStateNode 構造体をノードとする木構造のグラフのクラス.
const RobotStateNode & GetRootNode() const
グラフの根ノードの参照を返す.
std::vector< float > GetCoMVerticalTrajectory(const int index) const
指定したノードの重心の上下移動軌跡を返す.
const RobotStateNode & GetParentNode(const int index, const int depth) const
指定したノードの親ノードの参照を返す.depthは親ノードの深さを指定する.
const RobotStateNode & GetNode(const int index) const
グラフのノードの参照を返す.
constexpr bool HasRoot() const
グラフが根ノードを持つかどうかを返す. 根ノードとは,親を持たないノードのこと. 一番最初に追加するノードは必ず根になるため, 根を持つかどうかはノードの総数が0でないかどうかで判定できる.
constexpr int GetGraphSize() const
グラフのノードの総数を返す.
bool LeftIsBetter(const GraphSearchEvaluationValue &left, const GraphSearchEvaluationValue &right, bool return_true_case_of_equal=true) const
2つの評価値を比較する.左側の評価値が良い場合は true を返す.
GraphSearchEvaluationValue InitializeEvaluationValue() const
評価値を初期化する. 自身の持つ評価方法を用いて,評価値を初期化する.
std::tuple< GraphSearchResult, GraphSearchEvaluationValue, RobotStateNode > SearchGraphTreeVector(const std::vector< GaitPatternGraphTree > &graph_vector, const RobotOperation &operation, const DividedMapState ÷d_map_state, int max_depth) const override
std::tuple< GraphSearchResult, GraphSearchEvaluationValue, RobotStateNode > SearchGraphTree(const GaitPatternGraphTree &graph, const RobotOperation &operation, const DividedMapState ÷d_map_state, int max_depth) const override
グラフを受け取り,その中から最適な次の動作を出力する.
GraphSearcherStraightMove(const std::shared_ptr< const IHexapodPostureValidator > &checker_ptr)
static constexpr int kLegNum
void OutputF(OutputDetail detail, const std::format_string< Args... > str, Args &&... args)
コマンドラインに文字を出力する関数, format した文字列を出力する. SetOutputLimit() で設定した出力の許可範囲内であれば出力される.
void DebugOutputF(const std::format_string< Args... > str, Args &&... args)
コマンドラインに文字を出力する関数. Debug 用の出力. format した文字列を出力する.
bool IsGrounded(const LegStateBit &leg_state, const int leg_index)
脚番号 leg_index 0 ~ 5 に応じて,その脚が接地しているかを調べる. 脚は右前脚を0番として,時計回りに0,1,2,3,4,5となる.左前足が5番.
constexpr bool IsEqual(const T num1, const T num2) noexcept
C++において,小数同士の計算は誤差が出てしまう. 誤差込みで値が等しいか調べる.
std::string EnumToStringRemoveTopK(const T &enum_value)
enumを文字列に変換する関数. Google C++ coding style だと enumの要素は 先頭にkをつけてキャメルケースで書くことが推奨されている....
@ kStraightMoveVector
直線移動をさせる(移動したい方向をベクトルで示す)
@ kStraightMovePosition
直線移動をさせる(移動したい座標を示す)
@ kDebug
デバッグ時のみ出力,一番優先度が低い.
HexapodMove
ロボットが次にどの動作をするのかを表す列挙体.
std::map< Tag, float > value
bool is_lower_better
評価値が小さいほど良い場合は true.
探索において目標となる座標や角度,評価する値についてまとめた構造体.
Vector3 straight_move_vector
< 目標方向.正規化されたベクトル.
RobotOperationType operation_type
Vector3 straight_move_position
目標姿勢 ( posture )
Vector3 center_of_mass_global_coord
[4 * 3 = 12byte] グローバル座標系における重心の位置.旧名 GCOM
int depth
[4 byte] 自身の深さ.一番上の親が深さ0となる.
Vector3 GetNormalized() const noexcept
単位ベクトルを返す. normalizeとは,ベクトルを正規化(単位ベクトルに変換)する操作を表す. 絶対値が0のベクトルの場合,そのまま0ベクトルを返す.
static constexpr Vector3 GetFrontVec() noexcept
正面に進む単位ベクトルを返す. 静的な関数なので,Vector3::GetFrontVec() と呼び出せる.
float GetLength() const noexcept
ベクトルの長さを返す.