爪車

ヒト型ロボット 192

あまり進捗がないので、載せていなかったロボットの写真を公開します。
一年以上前のものです。既に分解されています。



20170603-2.jpg

AliExpressで中国から卓上リフロー炉T962を買いました。

基板設計していたら、4月分の更新を忘れてしまいました。

HoloLens買いました。

切削後の油べたべたの洗浄のために、超音波洗浄器を買ってみました。
シチズン 超音波洗浄器 SWT710
結構良い感じです。

ROBO-ONE初観戦。
とても面白かったです。

そのうち出場してみたいです。

今月は進捗無。

大量の荷物を送るときは、ヤマト便が便利。

SVG描画

SVGをポリゴンとして描画
nanosvgでパースしてpoly2triで三角ポリゴンに分割
パス単位でマウスピッキング可

Screenshot- 20160630
微妙に細部がおかしい

座標軸の色

座標軸と色の組み合せが、(X:赤, Y:青, Z:緑)という異端な組み合わせだったので修正。


修正前 (X:赤, Y:青, Z:緑)

Screenshot-20160531-2.png
修正後 (X:赤, Y:緑, Z:青)

(X:赤, Y:青, Z:緑)だったのは、(前:赤, 横:青, 上:緑)の組み合わせが個人的にしっくりしていたからという理由です。

来年から本気出す。

3D描画ライブラリ公開

ロボット開発に使用している3D描画ライブラリをGitHubで公開しました。
OpenGLのバックエンドとして、QtOpenGLとGLFWに対応しています。

TinyGraphicsLibrary
https://github.com/tsumeguruma/TinyGraphicsLibrary

Screenshot-20140216.png

まだまだ不完全です。

ミニ卓上CNCフライス盤購入

旋盤市場のPSF240-CNC ミニ卓上CNCフライス盤を購入しました。



結構大きい&重い。
持ち上げられなかったので引きずって移動しました。

一緒にコレットチャックセットとクイックバイスを購入。
オイルトレイは購入だったのに注文し忘れました・・・。

これで、立体的なものを切削する予定です。

来年から本気出す。

順運動学と逆運動学のプログラム

順運動学と逆運動学(6自由度)の簡易的なプログラム。
6自由度のリンクのみに対応しています。
本格的に用いるなら、OpenHRPChoreonoidの導入をお勧めします。

以下のコードはChoreonoidのソースコードを参考にしています。
行列計算にはEigenライブラリを用いています。

#include <iostream>
#include <string>
#include <Eigen/Core>
#include <Eigen/Geometry>
class Link;
double rad2deg(double rad); // radianからdegreeへ変換
double deg2rad(double deg); // degreeからradianへ変換
Eigen::Matrix3d rodrigues(const Eigen::Vector3d& axis, double q); // ロドリゲスの式
Eigen::Vector3d omegaFromRot(const Eigen::Matrix3d& R); // 行列対数関数
void calcForwardKinematics(Link* link); // 順運動学
Eigen::MatrixXd calcJacobian(Link* links, int numLinks, Link* targetLink); // ヤコビアンの計算
void calcInverseKinematics(Link* links, int numLinks, Link* targetLink, const Eigen::Vector3d& target_p, const Eigen::Matrix3d& target_R); // 逆運動学
Eigen::Matrix3d rotFromRpy(double r, double p, double y); // roll, pitch, yawから回転行列を求める
class Link
{
public:
Link() {
parent = NULL;
child = NULL;
sibling = NULL;
p.setZero();
R.setIdentity();
q = 0.0;
b.setZero();
a.setZero();
}
virtual ~Link() {}
std::string name; // リンクの名前
Link* parent; // 親リンク
Link* child; // 子リンク
Link* sibling; // 兄弟リンク
Eigen::Vector3d p; // 位置
Eigen::Matrix3d R; // 姿勢
double q; // 回転角度
Eigen::Vector3d b; // 親リンクからの相対位置
Eigen::Vector3d a; // 回転軸
};
// radianからdegree
double rad2deg(double rad)
{
return (180/M_PI) * rad;
}
// degreeからradian
double deg2rad(double deg)
{
return (M_PI/180) * deg;
}
// ロドリゲスの式
Eigen::Matrix3d rodrigues(const Eigen::Vector3d& axis, double q) {
return Eigen::AngleAxisd(q, axis).toRotationMatrix();
}
// 行列対数関数
// Choreonoid 1.4.0 から借用
Eigen::Vector3d omegaFromRot(const Eigen::Matrix3d& R)
{
    double alpha = (R(0,0) + R(1,1) + R(2,2) - 1.0) / 2.0;
    if(fabs(alpha - 1.0) < 1.0e-6) {   //th=0,2PI;
        return Eigen::Vector3d::Zero();
    } else {
        double th = acos(alpha);
        double s = sin(th);
        if (s < std::numeric_limits<double>::epsilon()) {   //th=PI
            return Eigen::Vector3d( sqrt((R(0,0)+1)*0.5)*th, sqrt((R(1,1)+1)*0.5)*th, sqrt((R(2,2)+1)*0.5)*th );
        }
        double k = -0.5 * th / s;
        return Eigen::Vector3d((R(1,2) - R(2,1)) * k,
                       (R(2,0) - R(0,2)) * k,
                       (R(0,1) - R(1,0)) * k);
    }
}
// 順運動学
void calcForwardKinematics(Link* link)
{
if (!link) return;
Link* parent = link->parent;
if (parent) {
link->p = parent->p + parent->R * link->b;
link->R = parent->R * rodrigues(link->a, link->q);
}
calcForwardKinematics(link->sibling);
calcForwardKinematics(link->child);
}
// ヤコビアンの計算
Eigen::MatrixXd calcJacobian(Link* links, int numLinks, Link* targetLink)
{
Eigen::MatrixXd J(6, numLinks); // (位置+姿勢の6自由度 x Joint数)
for (int i = 0; i < numLinks; ++i) {
Link* link = &links[i];
Eigen::Vector3d omega = link->R * link->a;
Eigen::Vector3d arm = targetLink->p - link->p;
Eigen::Vector3d dp = omega.cross(arm);
J(0, i) = dp(0);
J(1, i) = dp(1);
J(2, i) = dp(2);
J(3, i) = omega(0);
J(4, i) = omega(1);
J(5, i) = omega(2);
}
return J;
}
// 逆運動学 (6自由度)
void calcInverseKinematics(Link* links, int numLinks, Link* targetLink, const Eigen::Vector3d& target_p, const Eigen::Matrix3d& target_R)
{
    const int MAX_IK_ITERATION = 50;
    const double lambda = 0.5;
Link* rootLink = &links[0];
    Eigen::VectorXd dq(numLinks);
    Eigen::VectorXd v(6);
    for (int i = 0; i < MAX_IK_ITERATION ; ++i) {
    Eigen::MatrixXd J = calcJacobian(links, numLinks, targetLink);
    Eigen::Vector3d dp = target_p - targetLink->p;
    Eigen::Vector3d omega = targetLink->R * omegaFromRot(targetLink->R.transpose() * target_R);
    // 誤差の計算
    double err = sqrt(dp.dot(dp) + omega.dot(omega));
    if (err < 1e-6) {
//     std::cout << "err = " << err << std::endl;
//     std::cout << "iteration = " << i << std::endl;
    break;
    }
    v << dp, omega;
    dq = J.inverse() * v;
    for (int j = 0; j < numLinks; ++j) {
    links[j].q += lambda * dq(j);
    }
    calcForwardKinematics(rootLink);
    }
}
// roll, pitch, yawから回転行列を求める
// Choreonoid 1.4.0 から借用
Eigen::Matrix3d rotFromRpy(double r, double p, double y)
{
    const double cr = cos(r);
    const double sr = sin(r);
    const double cp = cos(p);
    const double sp = sin(p);
    const double cy = cos(y);
    const double sy = sin(y);
    Eigen::Matrix3d R;
    R << cp*cy, sr*sp*cy - cr*sy, cr*sp*cy + sr*sy,
         cp*sy, sr*sp*sy + cr*cy, cr*sp*sy - sr*cy,
         -sp  , sr*cp           , cr*cp;
    return R;
}
int main(int argc, char* argv[])
{
enum {
HIP_Y = 0,
HIP_R,
HIP_P,
KNEE_P,
ANKLE_P,
ANKLE_R,
NUM_LINKS
};
// リンクの設定
Link links[NUM_LINKS];
links[HIP_Y].name = "HIP_Y";
links[HIP_Y].parent = NULL;
links[HIP_Y].child = &links[HIP_R];
links[HIP_Y].b << 0.0, 0.0, 0.0;
links[HIP_Y].a << 0.0, 0.0, 0.1; // yaw
links[HIP_R].name = "HIP_R";
links[HIP_R].parent = &links[HIP_Y];
links[HIP_R].child = &links[HIP_P];
links[HIP_R].b << 0.0, 0.0, 0.0;
links[HIP_R].a << 1.0, 0.0, 0.0; // row
links[HIP_P].name = "HIP_P";
links[HIP_P].parent = &links[HIP_R];
links[HIP_P].child = &links[KNEE_P];
links[HIP_P].b << 0.0, 0.0, -0.02;
links[HIP_P].a << 0.0, 1.0, 0.0; // pitch
links[KNEE_P].name = "KNEE_P";
links[KNEE_P].parent = &links[HIP_P];
links[KNEE_P].child = &links[ANKLE_P];
links[KNEE_P].b << 0.0, 0.0, -0.1;
links[KNEE_P].a << 0.0, 1.0, 0.0; // pitch
links[ANKLE_P].name = "ANKLE_P";
links[ANKLE_P].parent = &links[KNEE_P];
links[ANKLE_P].child = &links[ANKLE_R];
links[ANKLE_P].b << 0.0, 0.0, -0.1;
links[ANKLE_P].a << 0.0, 1.0, 0.0; // pitch
links[ANKLE_R].name = "ANKLE_R";
links[ANKLE_R].parent = &links[ANKLE_P];
links[ANKLE_R].child = NULL;
links[ANKLE_R].b << 0.0, 0.0, 0.0;
links[ANKLE_R].a << 1.0, 0.0, 0.0; // row
// 順運動学
links[HIP_Y].q   = 0.0;
links[HIP_R].q   = 0.0;
links[HIP_P].q   = deg2rad(-45);
links[KNEE_P].q  = deg2rad(90);
links[ANKLE_P].q = deg2rad(-45);
links[ANKLE_R].q = 0.0;
Link* rootLink = &links[HIP_Y];
std::cout << "ForwardKinematics" << std::endl;
calcForwardKinematics(rootLink);
std::cout << "ANKLE_R p = " << links[ANKLE_R].p.transpose() << std::endl;
std::cout << "ANKLE_R R = \n" << links[ANKLE_R].R << std::endl;
// 逆運動学
Eigen::Vector3d target_p;
Eigen::Matrix3d target_R;
target_p << 0.0, 0.01, -0.12;
// target_R = rotFromRpy(0.0, deg2rad(10), 0.0);
target_R.setIdentity();
std::cout << "InverseKinematics" << std::endl;
calcInverseKinematics(links, NUM_LINKS, &links[ANKLE_R], target_p, target_R);
std::cout << "ANKLE_R p = " << links[ANKLE_R].p.transpose() << std::endl;
std::cout << "ANKLE_R R = \n" << links[ANKLE_R].R << std::endl;
return 0;
}

PC購入

新しいPCを買いました。

CPU : Intel Core i7 4770
GPU : NVIDIA GTX 560

CUDAで遊んでみたい。

あけましておめでとうございます。

ccacheでビルド時間の短縮

最近ccacheというものを知りました。
コンパイル結果をキャッシュすることで再コンパイル時間を短縮してくれます。

使用方法は簡単に

ccache g++ main.cpp

てな感じです。

qmakeで利用する場合は
QMAKE_CXX = ccache g++

cmakeの場合は
set(CXX="ccache g++")

参考ページ
ccacheで再コンパイル処理を高速化

ヒト型ロボット 85 GUI

少しずつ、モーション編集プログラムの開発を進めています。

GUIでカメラ操作。



Qtは楽でいいです。

MMDAgentα版公開

いつの間にやらMMDAgentが公開されていました。
http://www.mmdagent.jp/

Windowsのバイナリ版を試してみましたが、自分の環境ではエラーがでて動作しませんでした。
(Vista 32bit)

OSGメモ 隠れたポリゴンの描写

OpenSceneGraphのメモ

デプステストによって描写されないポリゴンを描写。
試行錯誤で何とかできました。

オブジェクトの描写順に関係なく、描写できると思います。

before


after
Screenshot-20101210-2.png

 #include <osg/Geode>
#include <osg/Geometry>
#include <osg/ShapeDrawable>
#include <osg/CullFace>
#include <osgViewer/Viewer>

osg::Node* createScene()
{
osg::Group* root = new osg::Group;

// box 1
{
osg::Geode* geode = new osg::Geode;
osg::ShapeDrawable* drawable = new osg::ShapeDrawable;
osg::Box* box = new osg::Box;
box->setCenter(osg::Vec3(-1, -1, -1));
box->setHalfLengths(osg::Vec3(0.9, 0.9, 0.9));

drawable->setColor(osg::Vec4(1, 0, 0, 1));

drawable->setShape(box);
geode->addDrawable(drawable);

root->addChild(geode);
}

// box 2
{
osg::Geode* geode = new osg::Geode;
osg::ShapeDrawable* drawable = new osg::ShapeDrawable;
osg::Box* box = new osg::Box;
box->setCenter(osg::Vec3(0, 0, 0));
box->setHalfLengths(osg::Vec3(0.5, 0.5, 0.5));

drawable->setColor(osg::Vec4(0, 1, 0, 0.5));

osg::StateSet* stateset = drawable->getOrCreateStateSet();

// 隠面消去
osg::CullFace* cull = new osg::CullFace;
cull->setMode(osg::CullFace::BACK);
stateset->setAttributeAndModes(cull, osg::StateAttribute::ON);

// DepthTest Off
stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);

//
stateset->setRenderBinDetails(11, "RenderBin");

drawable->setShape(box);
geode->addDrawable(drawable);

root->addChild(geode);
}

// box 3
{
osg::Geode* geode = new osg::Geode;
osg::ShapeDrawable* drawable = new osg::ShapeDrawable;
osg::Box* box = new osg::Box;
box->setCenter(osg::Vec3(1, 1, 1));
box->setHalfLengths(osg::Vec3(0.9, 0.9, 0.9));

drawable->setColor(osg::Vec4(0, 0, 1, 1));

drawable->setShape(box);
geode->addDrawable(drawable);

root->addChild(geode);
}

return root;
}

int main(int argc, char* argv[])
{
osgViewer::Viewer viewer;

viewer.setSceneData(createScene());

return viewer.run();
}

OpenHRP3 + drawstuff

OpenHRP3の敷居を少しでも下げてみたいと思い、いろいろとやってみたのですが、面倒になったので途中で投げ出すことに。
これでいっぱいいっぱいです。申し訳ありません。

OpenHRP3を動力学シミュレータとして利用し、ODE付属のdrawstuffで描写を担当させるサンプル。

・環境
Ubuntu9.10
OpenHRP version 3.1.0-Release バイナリパッケージからインストール
ode-0.11.1

Screenshot-20101029.jpg
実行例

・c++ソース
main.txt
.txtから.cppに変更してください。

・cmake用のCMakeList.txt
CMakeLists.txt

・サーバー群立ち上げのためのスクリプト
openhrp-startup-servers.txt
.txtから.shに変更してください。

・プログラム実行の流れ
スクリプトで
openhrp-model-loader
openhrp-aist-dynamics-simulator
openhrp-collision-detector
らをいっぺんに立ち上げ。
その後、コンパイルしたプログラムを別端末で実行。

・補足
・コードの大部分はOpenHRP3公式サイトからのものです。
・パスは適当に修正してください。
・つぎはぎです。
・不要なコードが混じっているかも。
・ODEに付属のdrawstuffを描写ライブラリとして利用。
・drawstuffの関数は回転行列がR[12]なので、ラップ関数を用意してR[9]に変換。ついでにdouble -> floatへも変換。

メモ makeの並列処理

makeの-jオプションで並列処理ができるようです。

最近初めて知りました。

-jの後に並列実行するジョブの個数を指定します。
デュアルコアの場合は
make -j2
のような感じです。

OpenHRP version 3.1.0 Release

9月21日にOpenHRP version 3.1.0-Releaseがリリースされたようです。

Ver.3.1.0β4からの変更点を確認した後、アップデートしたいと思います。

動作パターン設計ツールの公開は、まだなのかな?
ずっと楽しみに待っているのですが・・・

QtとCORBA

QtとCORBAを組み合わせてみようとしたのですが、どうもうまくいかない。

検索して調べてみたら、QtとCORBAの組み合わせは、よろしくないみたいです。
以前のバージョンのQtではCORBAを扱うモジュールがあったみたいですが、現在では商用版のQtでのみのサポートとなっており、使用は非推奨。

代わりに現在のQtではD-Busを扱うQDBusモジュールが用意されています。
詳しいことはまだ理解していないのですが、D-BusもCORBAと同じように、アプリケーション間のやりとりを行う技術のようです。

やっと・・・

やっとBLACKIIで、まともに加工できるようになりました。



切り込みステップを0.1mm、切削送りを200mm/minの設定で加工。

3本目・・・

エンドミル折れた・・・これで3本目。

アルミの切削は困難を極める。

切削中の筐体のビビリがものすごい。
すさまじい騒音が発生。

切削中に、エンドミルがアルミに引っかかり、スピンドルの回転が止まる。
送りは止まらないので、エンドミルはぽっきりと折れてしまう。

まともに切削できやしない。

心が折れそう。

試切削

BLACKIIで試切削してみました。

とりあえず適当な形をCADで作製。
材料はMDF材です。

初めての切削なので見守りながら開始したのですが、いきなりエンドミルが捨て板を貫通しそうになったので、緊急停止。
切り込み深さの設定をミスっていたようです。

設定しなおして、再び切削。

今度は上手くいきました。



加工時間は20分ほど。
切削粉は掃除機で吸い取りました。

DSCN1306.jpg

綺麗に切削できて喜んでいたのですが、材料の固定に使用した両面テープが強力すぎて、捨て板からはがせない、というなんとも間抜けな事態に。

BLACKII 1520の組み立て完了

ここ一週間ほど忙しくて、しばらく組み立てを放置していましたが、やっと完成。

まとまった時間が取れなかったため、完成が伸びてしまいましたが、一気にやれば2日ほどで組み立てられるのではないでしょうか。
説明書も丁寧なので、難なく組めると思います。

DSCN1295.jpg

設置場所に困っています。

設備投資

オリジナルマインド社のmini-CNC BLACKII 1520を購入しました。



現在、組み立て中。

Top|Next »

HOME

tsumehashi

Author:tsumehashi
FC2ブログへようこそ!

10 | 2017/11 | 12
- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 - -