GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
node_creator_com_up_down.cpp
[詳解]
1
3
4// Copyright(c) 2023-2025 Design Engineering Laboratory, Saitama University
5// Released under the MIT license
6// https://opensource.org/licenses/mit-license.php
7
9
10#include <algorithm>
11#include <cfloat>
12
13#include "math_util.h"
14#include "graph_search_const.h"
15#include "hexapod_const.h"
16#include "leg_state.h"
17#include "phantomx_mk2_const.h"
18
19
20namespace designlab
21{
22
24 const DividedMapState& divided_map,
25 const std::shared_ptr<const IHexapodCoordinateConverter>& converter_ptr,
26 const std::shared_ptr<const IHexapodStatePresenter>& presenter_ptr,
27 const std::shared_ptr<const IHexapodPostureValidator>& checker_ptr,
28 HexapodMove next_move) :
29 map_(divided_map),
30 converter_ptr_(converter_ptr),
31 presenter_ptr_(presenter_ptr),
32 checker_ptr_(checker_ptr),
33 next_move_(next_move)
34{
35}
36
37
38void NodeCreatorComUpDown::Create(const RobotStateNode& current_node, const int current_num,
39 std::vector<RobotStateNode>* output_graph) const
40{
41 // 重心を最も高くあげることのできる位置と,最も低く下げることのできる位置を求める.
42
43 // マップの最大z座標を求める.
45 float map_highest_z = -100000;
46
47 if (map_.IsInMap(current_node.center_of_mass_global_coord))
48 {
49 const int map_index_x = map_.GetDividedMapIndexX(current_node.center_of_mass_global_coord.x);
50 const int map_index_y = map_.GetDividedMapIndexY(current_node.center_of_mass_global_coord.y);
51 map_highest_z = map_.GetTopZ(map_index_x, map_index_y);
52 }
53
54 for (int i = 0; i < HexapodConst::kLegNum; i++)
55 {
56 // 脚の先端の座標を求める.
57 const Vector3 kCoxaVec = converter_ptr_->ConvertRobotToGlobalCoordinate(
58 presenter_ptr_->GetLegBasePosRobotCoordinate(i),
59 current_node.center_of_mass_global_coord,
60 current_node.posture, true);
61
62 if (map_.IsInMap(kCoxaVec))
63 {
64 const int kCoxaX = map_.GetDividedMapIndexX(kCoxaVec.x);
65 const int kCoxaY = map_.GetDividedMapIndexY(kCoxaVec.y);
66 map_highest_z = (std::max)(map_.GetTopZ(kCoxaX, kCoxaY), map_highest_z);
67 }
68 }
69
70
71 // ロボットの重心の最も低く下げることのできるz座標と,
72 // 高くあげることができるz座標を求める.どちらもグローバル座標.
73 float highest_body_pos_z = map_highest_z + presenter_ptr_->GetGroundHeightMarginMax();
74 float lowest_body_pos_z = map_highest_z + presenter_ptr_->GetGroundHeightMarginMin();
75
76
77 // 最も高い地点を修正する.
78
79 for (int i = 0; i < HexapodConst::kLegNum; i++)
80 {
81 // 接地している脚についてのみ考える.
82 if (leg_func::IsGrounded(current_node.leg_state, i))
83 {
84 // 三平方の定理を使って,脚接地地点から重心位置をどれだけ上げられるか考える.
85 const float edge_c =
87 const float edge_b =
88 current_node.leg_pos[i].ProjectedXY().GetLength() - PhantomXMkIIConst::kCoxaLength;
89
90 const float edge_a = sqrt(math_util::Squared(edge_c) - math_util::Squared(edge_b));
91
92 // 接地脚の最大重心高さの中から一番小さいものを全体の最大重心位置として記録する._aは脚の接地点からどれだけ上げられるかを表しているので,グローバル座標に変更する.
93 highest_body_pos_z = (std::min)(
94 edge_a + current_node.center_of_mass_global_coord.z + current_node.leg_pos[i].z, highest_body_pos_z);
95 }
96 }
97
98 // ノードを追加する.
99 pushNodeByMaxAndMinPosZ(current_node, current_num, highest_body_pos_z,
100 lowest_body_pos_z, output_graph);
101}
102
103
104void NodeCreatorComUpDown::pushNodeByMaxAndMinPosZ(
105 const RobotStateNode& current_node, const int current_num, const float high,
106 const float low, std::vector<RobotStateNode>* output_graph) const
107{
108 // 重心を変化させたものを追加する.変化量が一番少ないノードは削除する.
109
110 // 最大と最小の間を分割する.
111 const float kDivZ = (high - low) / static_cast<float>(kDiscretization);
112
113 // 分割した分新しいノードを追加する.
114 for (int i = 0; i < kDiscretization + 1; ++i)
115 {
116 bool is_valid = true;
117
118 RobotStateNode new_node = current_node;
119
120 // 重心の位置を変更する.
121 Vector3 new_com = current_node.center_of_mass_global_coord;
122 new_com.z = low + kDivZ * i;
123
124 new_node.ChangeGlobalCenterOfMass(new_com, true);
125
126
127 for (int j = 0; j < HexapodConst::kLegNum; j++)
128 {
129 if (!checker_ptr_->IsLegInRange(j, new_node.leg_pos[j]))
130 {
131 is_valid = false;
132 }
133 }
134
135 // current_numを親とする,新しいノードに変更する
136 new_node.ChangeToNextNode(current_num, next_move_);
137
138 // ノードを追加する.
139 if (is_valid)
140 {
141 (*output_graph).emplace_back(new_node);
142 }
143 }
144
145 // 重心の変化が一切ないものを追加する.
146 RobotStateNode same_node = current_node;
147
148 same_node.ChangeToNextNode(current_num, next_move_);
149
150 (*output_graph).emplace_back(same_node);
151}
152
153} // namespace designlab
マップを格子状に分割して管理するクラス.
constexpr int GetDividedMapIndexX(const float pos_x) const noexcept
指定した座標を DividedMap のインデックスに変換する. 範囲外の値を指定した場合でも,値を丸めずに返す. そのため,IsInMap で範囲内に存在するかどうかを確認する必要がある.
constexpr bool IsInMap(const float x, const float y) const
指定した座標がマップの範囲内に存在するかどうかを返す.
constexpr int GetDividedMapIndexY(const float pos_y) const noexcept
指定した座標を DividedMap のインデックスに変換する. 範囲外の値を指定した場合でも,値を丸めずに返す. そのため,IsInMap で範囲内に存在するかどうかを確認する必要がある.
float GetTopZ(int x_index, int y_index) const
格子状に切り分けられたマップから,最も高いZ座標を返す.
static constexpr int kLegNum
NodeCreatorComUpDown(const DividedMapState &devide_map, const std::shared_ptr< const IHexapodCoordinateConverter > &converter_ptr, const std::shared_ptr< const IHexapodStatePresenter > &presenter_ptr, const std::shared_ptr< const IHexapodPostureValidator > &checker_ptr, HexapodMove next_move)
void Create(const RobotStateNode &current_node, int current_num, std::vector< RobotStateNode > *output_graph) const override
現在のノードから次のノード群を生成する.
static constexpr float kFemurLength
第2関節部の長さ[mm].
static constexpr float kCoxaLength
第1関節部の長さ[mm].
static constexpr float kTibiaLength
第3関節部の長さ[mm].
bool IsGrounded(const LegStateBit &leg_state, const int leg_index)
脚番号 leg_index 0 ~ 5 に応じて,その脚が接地しているかを調べる. 脚は右前脚を0番として,時計回りに0,1,2,3,4,5となる.左前足が5番.
Definition leg_state.cpp:43
constexpr T Squared(const T num) noexcept
2乗した値を返す関数.
Definition math_util.h:59
HexapodMove
ロボットが次にどの動作をするのかを表す列挙体.
グラフ構造のためのノード(頂点).旧名 LNODE
std::array< Vector3, HexapodConst::kLegNum > leg_pos
[4 * 3 * 6 = 72 byte] 脚先の座標.(coxa(脚の付け根)を原点とする)
void ChangeGlobalCenterOfMass(const designlab::Vector3 &new_com, bool do_change_leg_base_pos)
重心位置を変更する関数.
leg_func::LegStateBit leg_state
[4 byte] 脚状態,重心パターンを bitで表す.旧名 leg_con.
constexpr void ChangeToNextNode(const int parent_index_, const HexapodMove next_move_)
次の動作を設定する関数. 深さを一つ深くして,親と次の動作を設定する.
Vector3 center_of_mass_global_coord
[4 * 3 = 12byte] グローバル座標系における重心の位置.旧名 GCOM
Quaternion posture
[4 * 4 = 16byte] 姿勢を表すクォータニオン.
3次元の位置ベクトルを表す構造体.
float x
ロボットの正面方向に正.
float z
ロボットの上向きに正.
float y
ロボットの左向きに正.