EnergyEfficiencyPanel.cpp
#include "StdAfx.h"
#include "EnergyEfficiencyPanel.h"
#include "Motion.h"
#include "Pose.h"
using namespace Core;
using namespace Robotics;
using namespace System;
using namespace System::Diagnostics;
/// [ Constructor ]
EnergyEfficiencyPanel::EnergyEfficiencyPanel( Motion^ motion )
{
// コンポーネントを初期化する
InitializeComponent();
// グラフの枠を取得する
ZedGraph::GraphPane^ graphPane = m_zedGraph->GraphPane;
graphPane->Title->IsVisible = false; // タイトル
graphPane->Legend->IsVisible = false; // 凡例
graphPane->Y2Axis->IsVisible = true; // 第2のY軸の表示
// 大きな格子の表示
graphPane->XAxis->MajorGrid->IsVisible = true;
graphPane->YAxis->MajorGrid->IsVisible = true;
// 軸ラベル
graphPane->XAxis->Title->Text = "時間[sec]";
graphPane->YAxis->Title->Text = "エネルギー効率[m/J]";
graphPane->Y2Axis->Title->Text = "エネルギー[J]";
// 軸ラベルの太字
graphPane->XAxis->Title->FontSpec->IsBold = false;
graphPane->YAxis->Title->FontSpec->IsBold = false;
graphPane->Y2Axis->Title->FontSpec->IsBold = false;
Drawing::Color efficiencyColor = Drawing::Color::Green; // エネルギー効率の色
Drawing::Color energyColor = Drawing::Color::Red; // エネルギーの色
// ... スケールの文字の色
graphPane->YAxis->Scale->FontSpec->FontColor = efficiencyColor;
graphPane->Y2Axis->Scale->FontSpec->FontColor = energyColor;
// ... 軸ラベルの文字の色
graphPane->YAxis->Title->FontSpec->FontColor = efficiencyColor;
graphPane->Y2Axis->Title->FontSpec->FontColor = energyColor;
// 反対側の軸の表示
graphPane->YAxis->MajorTic->IsOpposite = false;
graphPane->YAxis->MinorTic->IsOpposite = false;
graphPane->Y2Axis->MajorTic->IsOpposite = false;
graphPane->Y2Axis->MinorTic->IsOpposite = false;
/// @note
/// 第2の軸を表示するときには、反対側の軸を非表示にする。
// 軸の範囲
graphPane->YAxis->Scale->Max = 0.1;
graphPane->YAxis->Scale->Min = 0.0;
graphPane->Y2Axis->Scale->Max = 2.0;
graphPane->Y2Axis->Scale->Min = 0.0;
/// @todo
/// グラフの値から適切に設定されるようにする。
// モーションの変更イベントに登録する
motion->Changed += gcnew System::EventHandler( this, &EnergyEfficiencyPanel::MotionChanged );
// モーションの変更イベントを呼び出し、フィールドを初期化する
MotionChanged( motion, nullptr );
}
/// [ Destructor ]
EnergyEfficiencyPanel::~EnergyEfficiencyPanel()
{
if( components != nullptr )
{
delete components;
}
}
#pragma region Windows Form Designer generated code
/// <summary>
/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
/// コード エディタで変更しないでください。
/// </summary>
void EnergyEfficiencyPanel::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;
//
// EnergyEfficiencyPanel
//
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"EnergyEfficiencyPanel";
this->ShowHint = WeifenLuo::WinFormsUI::Docking::DockState::DockBottomAutoHide;
this->Text = L"EnergyEfficiency";
this->ResumeLayout(false);
}
#pragma endregion
/// モーションが変更された
void EnergyEfficiencyPanel::MotionChanged( System::Object^ sender, System::EventArgs^ )
{
// 引数から目的とする型を取得する。
Motion^ motion = safe_cast< Motion^ >( sender );
// グラフの点を生成する
ZedGraph::PointPairList^ energyPoint = gcnew ZedGraph::PointPairList();
ZedGraph::PointPairList^ efficiencyPoint = gcnew ZedGraph::PointPairList();
for( int i = 0; i < motion->PoseCount; i++ )
{
// ポーズの電力とモーションの単位時間を積算してエネルギー(電力量)を求める
double energy = motion[ i ]->ElectricPower * Motion::UnitTime;
// リンクの変位を取得する
const int bodyIndex = 0; // 胴体のインデックス番号
PositionVector^ displacement = motion->GetDisplacementOfLink( i, bodyIndex );
// ... X方向の変位をエネルギーで除して、エネルギー効率を求める
double efficiency = displacement->X / energy;
/// @todo
/// エネルギー効率の指標を、何を基準にするか選択できるようにする。
// グラフの点を追加する
energyPoint->Add( i * Motion::UnitTime, energy );
efficiencyPoint->Add( i * Motion::UnitTime, efficiency );
}
// グラフの枠を取得する
ZedGraph::GraphPane^ graphPane = m_zedGraph->GraphPane;
// ... グラフを消去する
graphPane->CurveList->Clear();
graphPane->GraphObjList->Clear();
// グラフの色を スケールの色から取得する
Drawing::Color efficiencyColor = graphPane->YAxis->Scale->FontSpec->FontColor;
Drawing::Color energyColor = graphPane->Y2Axis->Scale->FontSpec->FontColor;
// ... グラフの線を追加する
ZedGraph::LineItem^ curve;
curve = graphPane->AddCurve( "Efficiency", efficiencyPoint, efficiencyColor, ZedGraph::SymbolType::None );
curve = graphPane->AddCurve( "Energy", energyPoint, energyColor, ZedGraph::SymbolType::None );
curve->IsY2Axis = true; // 第2のY軸に指定
// 現在の時間を表すラインを生成する
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 = ( energyPoint->Count - 1 ) * Motion::UnitTime; // グラフの大きさ
if( graphPane->XAxis->Scale->Max != graphSize )
{
// X軸の最大値とグラフの大きさが異なっているならば、一致させる
graphPane->XAxis->Scale->Max = graphSize;
// ... 軸が変化したことを通知する
m_zedGraph->AxisChange();
}
// 表示を更新する
m_zedGraph->Invalidate();
}