Перейти на главную страницу
Федеральное агентство по образованию
ФГАОУ ВПО «Уральский Федеральный Университет имени первого
Президента России Б.Н. Ельцина»
Институт Образовательных Информационных Технологий
Кафедра «Информационные системы и технологии»
Оценка работы______________
Члены комиссии____________
Вариант 21.
Исполнитель: Тельгерекова А. В.,
студентка группы ИТ - 47011
Научный руководитель: Ждахин И. Л.
Екатеринбург
2011
Visual Simulation Environment -это ключевая часть Microsoft Robotics Developer Studio, которая использует 3D графику, чтобы сформировать изображение виртуального мира и физический движок (механизм) для
аппроксимации взаимодействия между объектами внутри физического мира. На первый взгляд, это выглядит примерно как игровой движок. Однако, после недолгого использования очень быстро становится очевидным, что они сильно различаются; не смотря на то, что многие действия и события записаны в игровой среде и то, что происходит в среде моделирования полностью зависит от взаимодействия и движения объектов в среде.
Модель содержит один или несколько объектов (сущностей), отображаемых внутри кадра. Каждый кадр модели формируется динамически, и не всегда известно заранее, какие силы будут действовать на объект внутри каждого кадра. Благодаря этому, можно работать не по плану и наблюдать, как робот будет взаимодействовать с окружающим миром.
MRDS предлагает несколько способов создания моделей и работы с ними. Возможно использование редактора VSE , а также можно добавлять объекты в модель программным способом: путем создания проекта службы DSS. MRDS предоставляет шаблон Visual Studio, который можно использовать для создания новой службы DSS.
Программное создание сервиса.
Все компоненты в Robotics Studio представляют собой независимо исполняемые сервисы и выступают как основополагающий элемент MRDS. Создадим собственный сервис. Рассмотрим, как добавить к среде симуляции небо, землю и несколько других объектов симуляции.
При создании проекта в Visual Studio, после установки Microsoft Robotics Developer Studio 2008, появился новый раздел Microsoft Robotics, в котором есть шаблон "DSS Service", предназначенный для создания сервисов.
рис.1. Использование шаблона для создания сервиса в Visual Studio
В этом разделе подробнее рассмотрим два файла исходного кода, которые генерируются при создании проекта: Corobot.cs, CorobotTypes.cs. Ниже будет описан файл-манифест.
Начинаться файл будет так:
Пространство имен основано на имени службы. Класс Contract является неотъемлемой частью контракта, и он должен содержать строковую переменную Identifier. Структура DSS не позволяет использовать обычное наследование, наследование может осуществляться через контракты. Контракт (Contract identifier) — уникальный идентификатор, позволяющий однозначно отличать один сервис от другого. Он определяет, каким должно быть состояние сервиса и какие операции можно с ним произвести. Контракт чем-то похож на интерфейсы (interface) из объектно-ориентированного программирования.
Концепция контракта проста: определяется состояние сервиса, набор типов сообщений и операционный порт. Контракты могут использоваться для различных моделей роботов, так как имеют общий интерфейс. Это позволяет различным приложениям работать с большим набором роботов. Приложению даже не известно, какому роботу передается сообщение, все они выглядят одинаково с точки зрения API.
Далее идет состояние службы с атрибутом [DataContract()]. Он необходим для того, чтобы класс был скопирован в Proxy DLL при компиляции.
Следующий фрагмент кода описывает основной порт операций (PortSet) с обязательным атрибутом [ServicePort].
Оканчивается файл определением типов запросов операций.
Стоит обратить внимание, что Get использует два обобщенных типа: GetrequestType для типов запросов и PortSet
Назначение всех трех атрибутов понятно из названия: отображаемое имя (DisplayName), описание (Description), контракт (Contract).
Рекомендуется использовать общепринятые имена для этих переменных: _state, _mainPort.
Следом идет обработчик, который должен быть помечен атрибутом [ServiceHandler()].
Двигаясь далее, изменим сервис так, чтобы он мог взаимодействовать с симулятором:
1. Вверху файла добавим следующие using операторы.
a) using-объявление (вводящее в данном пространстве имён (namespace) локальный синоним для элемента другого пространства)
b) using-директива (делающая доступными в данном пространстве имён (namespace) все имена из другого пространства имён)
#region Simulation namespaces
using Microsoft.Robotics.Simulation; // using-объявление
using Microsoft.Robotics.Simulation.Engine;
using engineproxy = Microsoft.Robotics.Simulation.Engine.Proxy;
using Microsoft.Robotics.Simulation.Physics;
using Microsoft.Robotics.PhysicalModel;
using xna = Microsoft.Xna.Framework; // using-директива
using xnagrfx = Microsoft.Xna.Framework.Graphics;
#endregion
2. Далее, необходимо задать ссылки на другие используемые службы: выбирается из списка dll-файлов (панель Solution Explorer → References)
рис.2. Добавление ссылок на DLL
Добавим ссылки на следующие DLL:
Microsoft.Xna.Framework
PhysicsEngine
RoboticsCommon
SimulationCommon
SimulationEngine
SimulationEngine.proxy
Microsoft.Xna.Framework.DLL. Эта библиотека содержит весь код визуализации. Она обеспечивает управляемый DirectX интерфейс и наконец вызывает лежащие в основе собственные библиотеки DirectX.
PhysicsEngine.DLL. Эта DLL содержит описание для объектов, использующихся в среде симуляции, которая изображает (воплощает, представляет) объекты в физическом движке.
Robotics.Common.DLL. Эта DLL определяет ряд общих типов и базовых контрактов, которые могут использовать как аппаратное обеспечение, так и сервисы моделирования.
Simulation.Common.DLL. Эта DLL определяет типы, которые используются только в среде моделирования. Типы, определенные для движка моделирования содержатся в пространстве имен Microsoft.Robotics
SimulationEngine.DLL. Эта DLL содержит большую часть функциональности симулятора, с точки зрения программиста, наиболее важные типы, они содержатся в пространстве имен Microsoft.Robotics.Simulation.
SimulationEngine.Proxy.DLL. Эта библиотека необходима для получения доступа к элементам сервиса движка симуляции. Такие элементы как контракты и определения портов должны всегда быть доступны из ProxyDLL.
3. После добавления ссылок на новые внешние библиотеки установим свойства CopyLocal и Specific Version в False. Построим сервис снова, чтобы гарантировать отсутствие ошибок.
4. Наверху класса CorobotService установим партнерство.
Contract = engineproxy.Contract.Identifier,
CreationPolicy = PartnerCreationPolicy.UseExistingOrCreate)]
private engineproxy.SimulationEnginePort _engineStub =
new engineproxy.SimulationEnginePort();
CameraView view = new CameraView();
view.EyePosition = new Vector3(-1.65f, 1.63f, -0.29f);
view.LookAtPoint = new Vector3(0, 0, 0);
SimulationEngine.GlobalInstancePort.Update(view);
Этот код определяет сообщение CameraView, устанавливает её EyePosition и LookAtPoint и потом посылает его сервису SimulationEngine. Это всё довольно просто до последней строчки, где размещается сообщение CameraView для SimulationEngine.GlobalInstancePort. Сервис GlobalInstancePort содержит статический глобальный указатель на его собственный главный порт управления. Это часто бывает неудобно для других служб симуляции взаимодействовать с SimulationEngine через этот порт.
6. Добавление неба к среде симуляции происходит простым добавлением следующих двух строк кода:
// Добавление небосвода.
SkyDomeEntity sky = new SkyDomeEntity(“skydome.dds”, “sky_diff.dds”);
SimulationEngine.GlobalInstancePort.Insert(sky);
Здесь создается новая сущность SkyDomeEntity и определяется внешняя текстура "skydome.dss" и текстура освещения "sky_diff.dss".
7. Сейчас добавим направленный свет, чтобы имитировать солнце. Без источника света, объекты в среде симуляции освещены только внешним светом и светом сущности SkyDome.
LightSourceEntity sun = new LightSourceEntity();
sun.State.Name = “Sun”;
sun.Type = LightSourceEntityType.Directional;
sun.Color = new Vector4(0.8f, 0.8f, 0.8f, 1);
sun.Direction = new Vector3(0.5f, -.75f, 0.5f);
SimulationEngine.GlobalInstancePort.Insert(sun);
HeightFieldEntity ground = new HeightFieldEntity(
“Ground”, // название
“Gravel.dds”, // изображение текстуры
new MaterialProperties(“ground”,
0.2f, // восстановление начального положения (реституция)
0.5f, // трение движения
0.5f) // трение покоя
);
SimulationEngine.GlobalInstancePort.Insert(ground);
SingleShapeEntity box = new SingleShapeEntity(
new BoxShape(
new BoxShapeProperties(
100, // масса в кг.
new Pose(), // относительное положение
dimensions)), // измерения
new Vector3(0, 1f, 29f * 2.54f / 100f + 1f));
// Название объекта. Все объекты должны иметь уникальное название.
box.State.Name = “box”;
// Вставка объекта в среду симуляции
SimulationEngine.GlobalInstancePort.Insert(box);
рис. 3. VSE
Определение собственного объекта - робота.
Первый шаг в создании робота в симуляторе - это определить новый класс (унаследованный от VisualEntity) следующим образом:
/// < summary >
/// Объект, который представляет Corobot. . Этот объект создан поворотом в ///положительном направлении оси Z, которое означает, что его передняя ///сторона имеет положительную Z координату. Передний и задний ИК- ///сенсоры включены наряду с фронтальной камерой.
[DataContract]
[DataMemberConstructor]
public class CorobotEntity : VisualEntity
{
}
Атрибут [DataContract] указывает, что этот объект имеет состояние, которое необходимо сериализовать (процесс перевода какой-либо структуры данных в последовательность битов), когда он передается по узлам.
/// < summary >
/// Конструктор по умолчанию используется когда его объект преобразован в ///параллельную форму.
/// < /summary >
public CorobotEntity()
{
}
/// Инициализация конструктора используется когда его объект построен путем ///программирования
/// < /summary >
/// < param name=”initialPos” > < /param >
public CorobotEntity(string name, Vector3 initialPos)
{
base.State.Name = name;
}
Конструктор не по умолчанию дает возможность определить объекту название и начальное положение.
Конструктор делает единственное действие - изменяет его состояние с передаваемыми параметрами. Параметры не должны быть инициализированы, когда конструктор по умолчанию вызван в течении
десериализации, потому что состоянию объекта будет восстановлено значение, которое он имел, когда объект был сериализован.
private static float InchesToMeters(float inches)
{
return (float)(inches * 2.54 / 100.0);
static float mass = 3.63f; // kg
static float chassisClearance = InchesToMeters(1.5f);
static float wheelGap = InchesToMeters(3f / 8f);
static float wheelWidth = InchesToMeters(2.2f);
static float wheelDiameter = InchesToMeters(4.75f);
static float wheelMass = 0.1f; // kg
static float platformClearance = InchesToMeters(5.75f);
static Vector3 platformDimensions = new Vector3(
InchesToMeters(11.0f),
InchesToMeters(3.0f),
InchesToMeters(8.5f));
static Vector3 chassisDimensions = new Vector3(
platformDimensions.X - 2 * wheelWidth - 2 * wheelGap,
InchesToMeters(2.5f),
platformDimensions.Z);
static Vector3 wheelFRPosition = new Vector3(
chassisDimensions.X / 2.0f + wheelGap + wheelWidth / 2.0f,
wheelDiameter / 2.0f,
-InchesToMeters(5.75f - 2.125f));
static Vector3 wheelFLPosition = new Vector3(
-wheelFRPosition.X,
wheelFRPosition.Y,
wheelFRPosition.Z);
static Vector3 wheelRRPosition = new Vector3(
wheelFRPosition.X,
wheelFRPosition.Y,
-wheelFRPosition.Z);
static Vector3 wheelRLPosition = new Vector3(
-wheelFRPosition.X,
wheelFRPosition.Y,
-wheelFRPosition.Z);
Положение переднего правого колеса вычислено, и положение остальных трех получено из него. Это дает информацию, чтобы определить основные физические формы, которые составляют физическую модель Corobot.
Колеса – это больше, чем просто фигуры - это целые объекты, с их собственной сеткой и физическими формами. Необходимо место чтобы хранить все четыре колеса, когда они будут созданы. Добавим код после конструктора.
// переменные объекта
WheelEntity _wheelFR;
WheelEntity _wheelFL;
WheelEntity _wheelRR;
WheelEntity _wheelRL;
[Category(“Wheels”)]
[DataMember]
public WheelEntity FrontRightWheel
{
get { return _wheelFR; }
}
[Category(“Wheels”)]
public WheelEntity FrontLeftWheel
{
get { return _wheelFL; }
}
[Category(“Wheels”)]
public WheelEntity RearRightWheel
{
get { return _wheelRR; }
}
[Category(“Wheels”)]
public WheelEntity RearLeftWheel
{
get { return _wheelRL; }
}
Атрибут Category только собирает в группу эти свойства вместе так, чтобы они были лучше организованы при просмотре в Simulation Editor.
Каждое свойство WheelEntity имеет атрибут [DataMember]. Этот атрибут сообщает proxy-генератору, какое из свойств должно быть сериализовано, когда объект посылается через удаленный узел или когда его сохраняют на диске. Только общие (public) свойства могут быть отмечены этим атрибутом.
Объекты колёс, шасси и фигуры платформы создаются в методе Initialize.
Добавим следующий код для переопределения метода Initialize основного класса
xnagrfx.GraphicsDevice device,
PhysicsEngine physicsEngine)
{
try
// шасси
“chassis”,
mass / 2.0f,
new Pose(new Vector3(
0,
chassisClearance + chassisDimensions.Y / 2.0f,
chassisDimensions);
chassisDesc.Material =
new MaterialProperties(“chassisMaterial”, 0.0f, 0.5f, 0.5f);
BoxShape chassis = new BoxShape(chassisDesc);
chassis.State.Name = “ChassisShape”;
base.State.PhysicsPrimitives.Add(chassis);
// платформа
BoxShapeProperties platformDesc = new BoxShapeProperties(
“platform”,
mass / 2.0f,
new Pose(new Vector3(
0,
platformClearance + platformDimensions.Y / 2.0f,
platformDimensions);
platformDesc.Material = chassisDesc.Material;
BoxShape platform = new BoxShape(platformDesc);
platform.State.Name = “PlatformShape”;
base.State.PhysicsPrimitives.Add(platform);
Первое, что делает метод Initialize - создает два ящика, чтобы изобразить шасси и платформу. Предполагается, что масса обоих одинакова, поэтому общая масса делится между ними. Им задают измерения и определенное положение. Эти позиции относительны началу координат объекта. Обеим фигурам задано схожее вещественное описание, которое определяет реституцию нулевого и среднего уровня статического трения. После создания каждой фигуры, добавляем к списку физических примитивов следующее:
base.CreateAndInsertPhysicsEntity(physicsEngine);
base.PhysicsEntity.SolverIterationCount = 128;
WheelShapeProperties wheelFRprop = new WheelShapeProperties(
“FrontRightWheel”, wheelMass, wheelDiameter / 2.0f);
WheelShapeProperties wheelFLprop = new WheelShapeProperties(
“FrontLeftWheel”, wheelMass, wheelDiameter / 2.0f);
WheelShapeProperties wheelRRprop = new WheelShapeProperties(
“RearRightWheel”, wheelMass, wheelDiameter / 2.0f);
WheelShapeProperties wheelRLprop = new WheelShapeProperties(
“RearLeftWheel”, wheelMass, wheelDiameter / 2.0f);
wheelFRprop.Flags |= WheelShapeBehavior.OverrideAxleSpeed;
wheelFLprop.Flags |= WheelShapeBehavior.OverrideAxleSpeed;
wheelRRprop.Flags |= WheelShapeBehavior.OverrideAxleSpeed;
wheelRLprop.Flags |= WheelShapeBehavior.OverrideAxleSpeed;
wheelFRprop.InnerRadius = 0.7f * wheelDiameter / 2.0f;
wheelFLprop.InnerRadius = 0.7f * wheelDiameter / 2.0f;
wheelRRprop.InnerRadius = 0.7f * wheelDiameter / 2.0f;
wheelRLprop.InnerRadius = 0.7f * wheelDiameter / 2.0f;
wheelFRprop.LocalPose = new Pose(wheelFRPosition);
wheelFLprop.LocalPose = new Pose(wheelFLPosition);
wheelRRprop.LocalPose = new Pose(wheelRRPosition);
wheelRLprop.LocalPose = new Pose(wheelRLPosition);
Далее, для каждого колеса определены WheelShapeProperties. Флаг OverrideAxesSpeed сообщает физическому движку то, что не нужно вычислять скорость оси, основанную на вращающем моменте мотора и трении. Это оказывается лучший способ, чтобы смоделировать типы моторов, которыми обычно управляют колесные роботы.
LocalPose каждой фигуры полезна, когда объект содержит множество фигур. Она определяет позицию и ориентацию каждой фигуры относительно начала координат объекта.
_wheelFR.State.Name = base.State.Name + “ FrontRightWheel”;
_wheelFR.Parent = this;
_wheelFR.Initialize(device, physicsEngine);
_wheelFL = new WheelEntity(wheelFLprop);
_wheelFL.State.Name = base.State.Name + “ FrontLeftWheel”;
_wheelFL.Parent = this;
_wheelFL.Initialize(device, physicsEngine);
_wheelRR = new WheelEntity(wheelRRprop);
_wheelRR.State.Name = base.State.Name + “ RearRightWheel”;
_wheelRR.Parent = this;
_wheelRR.Initialize(device, physicsEngine);
_wheelRL = new WheelEntity(wheelRLprop);
_wheelRL.State.Name = base.State.Name + “ RearLeftWheel”;
_wheelRL.Parent = this;
_wheelRL.Initialize(device, physicsEngine);
WheelEntity использует ссылку необычным способом. Вместо вызова CreateAndInsrtPhysicsEntity, WheelEntity вызывает InsertShape его родителя PhysicsEngine. Это добавляет фигуру WheelEntity к набору фигур, которые составляют его родителя. Что касается физического движка, фигуры колес это только часть родительского объекта. Это сокращает число требуемых вычислений физического движка, потому что он не вычисляет взаимодействия между колесами, шасси и платформой. Он предполагает, что они неподвижно соединены.
{
catch (Exception ex)
// очистить
if (PhysicsEntity != null)
PhysicsEngine.DeleteEntity(PhysicsEntity);
HasBeenInitialized = false;
InitError = ex.ToString();
}
}
Наконец, вызываем base.Initialize метод, который, между прочим, загружает любые сетки и текстуры связанные с объектом. Если сетка не задана в State.Assets.Mesh, простая сетка создастся из фигур в объекте.
SimulationEngine.GlobalInstancePort.Insert(
new CorobotEntity(“Corobot”, new Vector3(0, 0, 0)));
Этот код создал новый CorobotEntity с именем "Corobot" в начало координат среды моделирования. Скомпилируем и запустим сервис.
рис.4. Corobot
Программное создание собственного виртуального робота в Visual Studio для пакета mrds
11 10 2014
1 стр.
Охватывают также рп и ум. Динамические свойства датчика разрежения регулирующего органа характеризуются усилительным звеном, а объекта управления – апериодическим звеном с запаздыв
24 09 2014
1 стр.
Работа допущена к защите “ “ 20 г
17 12 2014
3 стр.
Комбинированные системы управления системы с отрицательной обратной связью, в которых измеряется одно или несколько возмущающих воздействий
12 10 2014
1 стр.
18 12 2014
1 стр.
12 10 2014
1 стр.
27 09 2014
8 стр.
Становление государственности и государственного управления в Киевской Руси (IX-XI вв.)
02 10 2014
1 стр.