概要
ロボットを道なりに走らせる場合など、走行させたい経路を点列で与えると便利な場合があります。 ここでは、点列で定義した連続直線(線分)に沿って走行させる方法を説明します。
点列で定義される連続直線の走行イメージ
点列と直線の定義
連続直線を構成する点が3つ与えられた場合、直線は2本定義できます。
3点から作られる2本の連続直線
ここで、連続直線を追従走行させるために、適当なタイミングで走行する直線を変えながら走行させることにします。
具体的には、何番目の直線を走行しているかを保持しておき、追従する直線を変更するタイミングまで移動したかを監視することにします。
追従する直線を変更するタイミング
追従する直線を変更するタイミングは、図の点 B を通り直線 AB に垂直な直線に、ある距離だけ点 A 側に寄せた直線です。
点 B に到達する少し前に走行する直線を指示することにより、滑らかに直線の乗り換えが行えます。
これらを実現するサンプルを以下に示します。
#include <iostream>
#include <vector>
using namespace hrk;
using namespace std;
namespace
{
void create_follow_lines(vector<PositionF>& lines,
const vector<PointF>& points)
{
if (points.size() <= 1) {
return;
}
vector<PointF>::const_iterator from_it = points.begin();
for (vector<PointF>::const_iterator to_it = from_it + 1;
to_it != points.end(); ++to_it, ++from_it) {
Angle angle = angle_to(*from_it, *to_it);
lines.push_back(
PositionF(to_it->x(), to_it->y(), angle));
}
}
void follow(
Run_driver& robot,
const vector<PositionF>& lines)
{
size_t line_index = 0;
while (true) {
-Line_change_distance) {
delay_sec(0.1);
}
size_t next_line_index = line_index + 1;
if (lines.size() <= next_line_index) {
return;
}
line_index = next_line_index;
}
}
}
int main(int argc, char *argv[])
{
static_cast<void>(argc);
static_cast<void>(argv);
if (!robot.
open(
"/dev/ttyUSB0")) {
cerr << FILE_POSITION() << robot.
what() << endl;
return 1;
}
vector<PointF> points;
points.push_back(
PointF(0.0, 0.0));
points.push_back(
PointF(1.0, 0.0));
points.push_back(
PointF(1.0, 1.0));
points.push_back(
PointF(2.0, 1.0));
vector<PositionF> lines;
create_follow_lines(lines, points);
follow(robot, lines);
wait_stable(robot, 0.1);
return 0;
}
実際は、このサンプルにセンサ情報の監視などの処理を追加する必要がありますが、基本はこのようなコードになります。