VelocityPanel.cpp

#include "StdAfx.h"
#include "VelocityPanel.h"


#include "Motion.h"
#include "Pose.h"


using namespace Core;
using namespace Robotics;

using namespace System;
using namespace System::Diagnostics;


/// [ Constructor ]
VelocityPanel::VelocityPanel( Motion^ motion ) :
    m_linkIndex( 0 )
{
    // コンポーネントを初期化する
    InitializeComponent();


    // グラフの枠を取得する
    ZedGraph::GraphPane^ graphPane = m_zedGraph->GraphPane;

    graphPane->Title->IsVisible = false;            // タイトル

    // 大きな格子の表示
    graphPane->XAxis->MajorGrid->IsVisible = true;
    graphPane->YAxis->MajorGrid->IsVisible = true;

    // 軸ラベル
    graphPane->XAxis->Title->Text = "時間[sec]";
    graphPane->YAxis->Title->Text = "速度[m/sec]";

    // 軸ラベルの太字
    graphPane->XAxis->Title->FontSpec->IsBold = false;
    graphPane->YAxis->Title->FontSpec->IsBold = false;


    // 軸の範囲
    graphPane->YAxis->Scale->Max = +0.1;
    graphPane->YAxis->Scale->Min = -0.1;

    /// @todo
    /// グラフの値から適切に設定されるようにする。


    // モーションの変更イベントに登録する
    motion->Changed += gcnew System::EventHandler( this, &VelocityPanel::MotionChanged );

    // モーションの変更イベントを呼び出し、フィールドを初期化する
    MotionChanged( motion, nullptr );
}

/// [ Destructor ]
VelocityPanel::~VelocityPanel()
{
    if( components != nullptr )
    {
        delete components;
    }
}


#pragma region Windows Form Designer generated code
/// <summary>
/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
/// コード エディタで変更しないでください。
/// </summary>
void VelocityPanel::InitializeComponent(void)
{
    this->components = (gcnew System::ComponentModel::Container());
    this->m_zedGraph = (gcnew ZedGraph::ZedGraphControl());
    this->SuspendLayout();
    //
    // m_zedGraph
    //
    this->m_zedGraph->Dock = System::Windows::Forms::DockStyle::Fill;
    this->m_zedGraph->EditButtons = System::Windows::Forms::MouseButtons::None;
    this->m_zedGraph->IsEnableHZoom = false;
    this->m_zedGraph->IsEnableVZoom = false;
    this->m_zedGraph->IsEnableWheelZoom = false;
    this->m_zedGraph->IsShowContextMenu = false;
    this->m_zedGraph->Location = System::Drawing::Point(0, 0);
    this->m_zedGraph->Name = L"m_zedGraph";
    this->m_zedGraph->ScrollGrace = 0;
    this->m_zedGraph->ScrollMaxX = 0;
    this->m_zedGraph->ScrollMaxY = 0;
    this->m_zedGraph->ScrollMaxY2 = 0;
    this->m_zedGraph->ScrollMinX = 0;
    this->m_zedGraph->ScrollMinY = 0;
    this->m_zedGraph->ScrollMinY2 = 0;
    this->m_zedGraph->Size = System::Drawing::Size(292, 272);
    this->m_zedGraph->TabIndex = 0;
    //
    // VelocityPanel
    //
    this->AutoScaleDimensions = System::Drawing::SizeF(6, 12);
    this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
    this->ClientSize = System::Drawing::Size(292, 272);
    this->CloseButton = false;
    this->Controls->Add(this->m_zedGraph);
    this->DockAreas = static_cast<WeifenLuo::WinFormsUI::Docking::DockAreas>(((WeifenLuo::WinFormsUI::Docking::DockAreas::Float | WeifenLuo::WinFormsUI::Docking::DockAreas::DockTop)
        | WeifenLuo::WinFormsUI::Docking::DockAreas::DockBottom));
    this->HideOnClose = true;
    this->Name = L"VelocityPanel";
    this->ShowHint = WeifenLuo::WinFormsUI::Docking::DockState::DockBottomAutoHide;
    this->Text = L"Velocity";
    this->ResumeLayout(false);

}
#pragma endregion


/// モーションが変更された
void VelocityPanel::MotionChanged( System::Object^ sender, System::EventArgs^ )
{
    // 引数から目的とする型を取得する。
    Motion^ motion = safe_cast< Motion^ >( sender );

    // グラフの点を生成する
    ZedGraph::PointPairList^ pointX = gcnew ZedGraph::PointPairList();
    ZedGraph::PointPairList^ pointY = gcnew ZedGraph::PointPairList();
    ZedGraph::PointPairList^ pointZ = gcnew ZedGraph::PointPairList();


    for( int i = 0; i < motion->PoseCount; i++ )
    {
        // 速度を求める
        PositionVector^ velocity = motion->GetVelocityOfLink( i, m_linkIndex );

        // グラフの点を追加する
        pointX->Add( i * Motion::UnitTime, velocity->X );
        pointY->Add( i * Motion::UnitTime, velocity->Y );
        pointZ->Add( i * Motion::UnitTime, velocity->Z );
    }


    // グラフの枠を取得する
    ZedGraph::GraphPane^ graphPane = m_zedGraph->GraphPane;

    // ... グラフを消去する
    graphPane->CurveList->Clear();
    graphPane->GraphObjList->Clear();

    // ... グラフの線を追加する
    ZedGraph::LineItem^ curve;
    curve = graphPane->AddCurve( "X", pointX, Drawing::Color::Red, ZedGraph::SymbolType::None );
    curve = graphPane->AddCurve( "Y", pointY, Drawing::Color::Green, ZedGraph::SymbolType::None );
    curve = graphPane->AddCurve( "Z", pointZ, Drawing::Color::Blue, ZedGraph::SymbolType::None );


    // 現在の時間を表すラインを生成する
    ZedGraph::LineObj^ currentTimeLine = gcnew ZedGraph::LineObj(
        Drawing::Color::Orange,         // 色
        motion->CurrentTime,
        graphPane->YAxis->Scale->Min,
        motion->CurrentTime,
        graphPane->YAxis->Scale->Max
        );

    // ... グラフのオブジェクトに追加する
    graphPane->GraphObjList->Add( currentTimeLine );


    double graphSize = ( pointX->Count - 1 ) * Motion::UnitTime;  // グラフの大きさ
    if( graphPane->XAxis->Scale->Max != graphSize )
    {
        // X軸の最大値とグラフの大きさが異なっているならば、一致させる
        graphPane->XAxis->Scale->Max = graphSize;

        // ... 軸が変化したことを通知する
        m_zedGraph->AxisChange();
    }

    // 表示を更新する
    m_zedGraph->Invalidate();
}


/// 対象を設定する
void VelocityPanel::SetTarget( int linkIndex, Motion^ motion )
{
    m_linkIndex = linkIndex;

    // モーションの変更イベントを呼び出し、表示を更新する
    MotionChanged( motion, nullptr );
}