Microsoft Robotics Developer Studio 4学习笔记-案例2-开始玩机器人

合集下载

robot studio 教程

robot studio 教程

robot studio 教程Robot Studio教程第一章概述1.1 介绍本教程旨在向用户提供有关Robot Studio的全面指南。

Robot Studio是一款强大的仿真软件,可以帮助用户设计、模拟和优化系统。

1.2 安装在本章节中,将介绍如何和安装Robot Studio软件。

包括软件的系统要求,安装步骤以及常见问题解答。

第二章界面导览2.1 主界面这一章节将详细介绍Robot Studio的主界面,包括菜单栏、工具栏、快捷键等,以及如何切换视图,访问不同的功能模块。

2.2 视图控制在本章节中,将提供一些关于如何调整和控制Robot Studio的视图,包括缩放、旋转、平移等操作。

第三章创建模型3.1 建立基本模型这一章节将展示如何在Robot Studio中创建基本的模型,包括添加机械臂、关节、夹爪等组件。

3.2 导入CAD模型在本章节中,将介绍如何导入现有的CAD模型,并将其转换为Robot Studio可识别的格式。

第四章仿真与调试4.1 运行仿真这一章节将详细介绍如何运行仿真,并演示一些常见的操作,如的移动、捡取物体等。

4.2 调试程序在本章节中,将学习如何使用Robot Studio调试程序,检查错误和调整程序逻辑。

第五章路径规划与优化5.1 路径规划算法这一章节将介绍Robot Studio中使用的路径规划算法,包括最短路径、最优路径等。

并提供一些优化建议和技巧。

5.2 优化参数在本章节中,将讨论如何优化的工作参数,如速度、加速度等,以提高的性能和效率。

第六章系统集成6.1 外部设备集成这一章节将介绍如何与其他外部设备进行集成,包括传感器、相机、控制器等。

6.2 与PLC通信在本章节中,将学习如何与PLC(可编程逻辑控制器)通信,实现与生产线的无缝连接。

第七章高级功能7.1 机器学习这一章节将探讨如何在Robot Studio中应用机器学习技术,提高的智能水平和自适应能力。

第17天Microsoft Robotics Developer Studio中文教程--CCR Overview

第17天Microsoft Robotics Developer Studio中文教程--CCR Overview

2. Dispatcher, DispatcherQueue, Task就好比Thread 執行程式碼, 在CCR 當中, 程式的運行是以ITask 作為執行的單位, 而DispatcherQueue 就是以Queue 的方式來存放許多的Tasks (以下我提到Task, 就是代表該class 有支援/實作ITask 的意思) , 最後, Dispatcher 就像是Thread, 用來執行運作DispatcherQueue (當中的Tasks). 不過在極少數的狀況下, DispatcherQueue 也可以被.NET Thread Pool 來運作.而Task 最重要的就是Handler, 就是Programmer 寫的delegate function.至於這許多的Tasks 從何而來, 如何產生, Handler (你的程式碼, delegate function) 何時要被執行, 就是要靠接下來介紹的Arbiter class.3. Arbiter class這是CCR 寫好的一組函式庫, 負責用來撰寫處理訊息所需要用到的協同處理函式. 通常使用者(programmer) 就是透過撰寫delegate function, 然後指定當某種情境發生時(比方說, Receive Task 就是某個Port 收到訊息時), CCR 就會執行該delegate function (透過ITask).以下我開始介紹Arbiter 的所有Member (都是static function, 所以都是直接使用), 這可是CCR 的重頭戲(不過我只介紹基本使用方法, 進階的使用方法就太多了):Arbiter.Recive產生一個Receive Task , 就是當某一個port 收到訊息時, 就執行Handler (某段程式碼).比方說, 以下的程式產生一個Receive Task, 就是當一個Port<int> 收到int 訊息時就把它從Console 輸出. (但是該Task 還不會被執行, 因為我們只是產生了Recive Task)var myport = new Port<int>();var mytask = Arbiter.Receive(true, myport, i => Console.WriteLine(i));其中, 第一個參數如果是true, 表示這個Task 一直都要存在, 不會消失, 如果是false, 則表示僅僅執行一次, 這個Task 就消失.Arbiter.Activate使用某個DispatcherQueue 來執行一系列的Tasks.比方說我們要產生一個DispatcherQueue, 然後利用該DispatcherQueue 來執行一個Receive Task, 就可以寫成下面這樣的code :var taskQueue = new DispatcherQueue("myqueue", new Dispatcher());var myport = new Port<int>();Arbiter.Activate(taskQueue, Arbiter.Receive(true, myport, msg => Console.WriteLine(msg)));如果接下來有程式執行myport.Post(3) , 就會啟動執行Receiver Task, 也就是在Console 印出3 .Arbiter.Choice有點像是switch case , 是屬於Task 的分支流程處理用的, 它會產生一個Choice Task , 而只會處理眾多Handlers 的其中之一(或眾多Tasks 的其中之一個Handler).14. // Persisted Get handler, runs in parallel with all other activations of itself15. // but never runs in parallel with Update or Stop16. Arbiter.Receive<GetState>(true, _mainPort, GetStateHandler)17. ))18.);// activate an Interleave Arbiter to coordinate how the handlers of the service// execute in relation to each other and to their own parallel activationsArbiter.Activate(_taskQueue,Arbiter.Interleave(new TeardownReceiverGroup(// one time, atomic teardownArbiter.Receive<Stop>(false, _mainPort, StopHandler)),new ExclusiveReceiverGroup(// Persisted Update handler, only runs if no other handler runningArbiter.Receive<UpdateState>(true, _mainPort, UpdateHandler)),new ConcurrentReceiverGroup(// Persisted Get handler, runs in parallel with all other activations of itself// but never runs in parallel with Update or StopArbiter.Receive<GetState>(true, _mainPort, GetStateHandler))));而CCR 實現這個Arbiter.Interleave 不是靠傳統的lock, 或是ReaderWriterLock, 而是靠內部的TaskQueue 來實作的, 它也不需要知道哪些資料是你所要保護的, 它只是負責避免哪些程式不可同時執行, 以及允許哪些程式可以同時執行.Arbiter.JoinedReceive假如你想要等候兩個Port 都分別收到訊息時才要作處理(執行Handler) 的話, 這個就是你要的.比方說下面的code:Arbiter.JoinedReceive<int, string>(false, myport, myport2, (intmsg,strmsg) =>Console.WriteLine(intmsg+","+strmsg))就是表示產生一個JoinedReceive Task, 當myport 收到int 訊息, myport2 收到string 訊息, (不管先後順序, 會一直等到兩個都收到訊息), 就在Console 作輸出.Arbiter.MultipleItemReceive跟Arbiter.JoinedReceive 不太一樣的地方在於, 它是看訊息的數量, 當一定數量的訊息送到一個或多個Port 的時候, 就會啟動Handler.比方說下面這個code 就是當累積五個int 訊息送到portInt 的時候, 就會啟動Handler, 把這五個int 輸出到螢幕上.Arbiter.MultipleItemReceive(true, portInt, 5,intArray => Console.WriteLine(string.Join(",", new List<int>(intArray).ConvertAll<string>(i =>i.ToString()).ToArray())));一旦你了解了Arbiter 的函式, 還有DSSP 的類型, 相信你再去看documentation 當中的。

Microsoft Robotics Studio 让机器人学更容易

Microsoft Robotics Studio 让机器人学更容易

/roboticsMicrosoft Robotics Studio 讓機器人學更容易________________________________________________________________________Microsoft Robotics Studio 讓在不同硬體平台設計機器人應用變的更容易了。

Microsoft Robotics Studio SDK 是一套簡易但又強大的動態平台,操作編寫及模擬工具時更容易,同時也擁有教學及樣本代碼來協助你開始使用這套軟體。

終端至終端的開發平台Microsoft Robotics Studio SDK 讓開發者可以設計多樣化的機器人硬體應用。

* 利用視覺性程式環境就可以簡單的設計應用。

透過視覺性程式語言(VPL )簡易化程式設計和除錯。

視覺化的服務區塊可被重複使用與堆集。

* 使用以物理為基礎的3D 視覺環境來模擬應用。

微軟Visual Simulation Environment 透過了AGEIA Technologies Inc.的AGEIA TMPhysXTM <來模擬真實世界物理、也可另用硬體加速PhysX 模擬。

* 即使在不同的硬體平台上也能夠輕鬆的更改硬體。

使用簡易的拖曳及丟下介面來更改服務。

* 用Windows 或網路為主的介面與機器人互動。

設計一個可以用Windows 介面或是網絡瀏覽器操控的機器人應用。

好比說:利用HTML 和JavaScript 遠距離的監控機器人的攝影機和感應網絡。

輕量的不同時與服務為重的動態 Microsoft Robotics Studio 擁有先進的服務導向的軟體平台。

* 讓非同步的程式運作變的簡易並行(Concurrency )及Concurrency and Coordination Runtime (CCR)函式庫讓處理多項機器人學感應器的非同步輸入與輸出至馬達和機動器的程式設計變得更簡單。

机器人的“操作系统”

机器人的“操作系统”

机器人的“操作系统”:Microsoft Robotic Studio――让你的机器人像个人电脑一样众所周知,微软公司(Microsoft Corp.)的Windows系列操作系统已经在个人电脑领域占据了主导地位。

无论您的机器是何种品牌、何种型号、何种配置,Windows操作系统都能够轻松应对并为您提供想要的服务。

同时,友好的用户界面也赢得了广大用户的青睐,使Windows成为个人电脑领域最受欢迎的操作系统。

如今,这一传统正在进入欣欣发展的机器人行业,而且不仅仅局限于家用机器人领域,在工业机器人领域也已经崭露头角。

这就是微软机器人工作室推出的机器人操作系统――Microsoft Robotic Studio。

在目前机器人行业的生产和开发过程中,还没有统一的平台和标准,不同公司按照不同的标准和技术路线生产和开发机器人设备。

对于机器人的初学者而言进入的门槛过高,每一个开发人员都要从底层硬件入手再到上层的控制软件,大量的人力物力消耗在了重复的设计中,为了改变这一局面,为机器人开发人员能减少一些麻烦的工作和创建不同类型硬件的标准,简化对机器人的编程,把更多的精力投入机器人智能领域的研究,2006年6月微软公司推出了“Microsoft Robotic Studio”机器人开发软件,迈出了向机器人行业进军的第一步。

微软公司于2008年5月19日在匹兹堡举办的 RoboBusiness Conference and Exposition(机器人商业大会暨展览会)上首次发布了其机器人技术编程平台的最新版本 Microsoft Robotics Developer Studio 2008 的社区技术预览版 (CTP)。

Microsoft Robotics Developer Studio 2008 包含对齐运行时间性能、分布式计算功能以及工具的改进。

这个被称为“Microsoft Robotics Studio”(微软机器人技术工作室)的新平台主要用于机器人技术的开发,适合学术、理论和商业研究等领域。

第20天Microsoft Robotics Developer Studio中文教程--Sumo[II] - 开始动手写相扑机器人

第20天Microsoft Robotics Developer Studio中文教程--Sumo[II] - 开始动手写相扑机器人

2./// This is the default drive configuration for wander mode3./// </summary>4.private void SetWanderDrive()5.{6. _state.SumoMode = SumoMode.Wander;7. InternalDrivingMilliseconds(250, 175, 250.0);8.}/// <summary>/// This is the default drive configuration for wander mode/// </summary>private void SetWanderDrive(){_state.SumoMode = SumoMode.Wander;InternalDrivingMilliseconds(250, 175, 250.0);}是不是很簡單呢, 它只做一個小幅度的繞圈圈...設定左輪的速度為250, 右輪的速度為175 , 然後等到250 ms 之後再進行新的決定.怎麼改會比較好?老實說我也不知道, 不過可以隨便亂改啊, 所以先改為原地順時鐘繞圈圈看看:InternalDrivingMilliseconds(250, -250, 250.0);然後讓mysumo 跟SumoPlayer (原本內定的機器人) 對打...有沒有發現我們的機器人大半的時候都是在原地旋轉呢?!有沒有發現我們的機器人似乎明明看到對手, 卻往前衝一下就停止, 繼續旋轉??所以, 下次我們來試試看Tracking Mode 到底在幹啥...在此之前, 你可以亂改SetWanderDrive 玩看看...你應該會有一些心得, 像是速度太快的話, 根本看不到對手... 就算你把反應時間調快也沒用.這是因為架構上是利用TimerHandler 這個函式去處理的, 而該函式預設是200 ms /4 = 50 ms 觸發一次...更何況預設是每200 ms 才去處理一次圖像...(這樣fps 才5 ... 你能想像5 fps 的射擊遊戲是甚麼樣子吧?)-->。

Microsoft Robotics Developer Studio 4学习笔记-案例2-开始玩机器人

Microsoft Robotics Developer Studio 4学习笔记-案例2-开始玩机器人

Microsoft Robotics Developer Studio 4学习笔记案例2:开始玩机器人1.为了看见车子,我们从“Service”中选择“Simulated Generic Differential Drive”放在“Diagram”上;①对“Simulated Generic Differential Drive”右击,选择“Set Configuration”;②跳到“Simulated Generic Differential Drive”的设定界面,选择“Use a manifest”;③选择“Import Manifest”,导入虚拟机器人;④选择“LEGO.NXT.Tribot.Simufation.Manifest.xml”⑤现在保存文件,运行后就能看到“乐高”虚拟机器人了。

2.为了操控虚拟机器人,从“service”中拖一个“Direction Dialog”到“Diagram”中,这个“Direction Dialog”会在系统中产生一个有上下左右及Stop的五个键,让我们可以编程后控制里面的机器人。

3.在“Basic Activities”中找到“Calculate”,把“Calculate”拉到“Diagram”中;①把“Direction Dialog”的“Notification(右下方的红圈)”拉到“Calculate”,表示把“Direction Dialog”的通知传递给“Calculate”,这时会弹出“Connections”对话框。

②选择“ButtonPress”表示:当鼠标被按下时。

③“DirectionDialog”跟“Calculate”连接后,在“Calculate”中间下拉选择“Name”,表示要从“ButtonPress”信息中,拆解出“Nmae”这个信息(被按下的按钮名称),这个被按下的按钮会被输出到“Calculate”的右端。

第8天Microsoft_Robotics_Developer_Studio中文教程--Hello_World_Again!_(DSS_Service_version)

第8天Microsoft_Robotics_Developer_Studio中文教程--Hello_World_Again!_(DSS_Service_version)

[Robotics Studio] Hello World Again! (DSS Service version) --Day8编辑整理<杜毓聪duyucong@ >太混了,第八天还在Hello World !事实是,我们开始往更深入的技术迈进啰,如果想要更深入了解RDS (Microsoft Robotics Developer Studio) ,我们要开始了解DSS (Decentralized Software Services)以及CCR (Concurrency And Coordination Runtime) ,虽然DSS以及CCR是随着RDS而出现,但其实它们可不需要限定于RDS才能使用欧,虽然我目前没有在.NET Framework 4.0当中发现他们的身影,但是随着多核心系统的进展,软件当然也是要能够发挥多核心的长处,随之而来的平行处理问题,当然是程序人员要面对的课题,有了CCR以及DSS这样的Framework ,开发平行处理程序时将会采用不同的逻辑思考与概念.如果你已经写了很多年的程序,相信对于之前的VPL觉得有些不太习惯,现在我要弄点程序人员习惯的东西,就是用Visual Sutdio 2008 (or VS 2008 Express Edition)来开发程序.但是我还是不会脱离VPL这个接口.为什么我要贴着VPL这个接口呢,因为RDS教学套件中有相当多关于DSS与CCR信息,但却都是单纯的Visual Sutdio操作,鲜少提及如何跟VPL整合,但我认为VPL才是适合初学者的良好接口,所以对于初学者而言,能够与这个接口整合,应该比较能够提起写code的兴趣.这就如同一开始如果教学采用Unix Command Line模式,相信很多人都受不了.但是如果一开始采用拖拉视觉操作系统方式,相信很多人都比较容易有兴趣,等到有了兴趣,再介绍更强大的命令列模式,就比较不会觉得排斥.况且,良好的视觉操作系统有时候比起命令列模式还棒,这点只要你看过VPL开发的程序经过Compile转成C#的程序后,你会承认VPL有时候是比较好的(当然不是所有状况,而是各有优缺点).OK!写了很多废话才开始写程序,这大概是年纪大了(爱碎碎念)才会这样吧??首先,在你安装完RDS以后,如果你有Visual Studio 2008 (or Express Edition) ,你应该可以在新增项目当中看到Microsoft Robotics Express ,像这样:按下确定以后,你会看到一个对话框:这是对话框可以让你输入DSS的名称,日期(用以跟其它同名的DSS区别),还可以输入Partners (一起合作的DSS Service) , Alternate Contracts (替代协议)我们可以都用预设的,因为我们现在只要写Hello World嘛...不过在开始撰写DSS Service之前,我想要先讲解DSS Service的大体架构:(这张图来自RDS官方文件)所以每一个DSS实体(Instance)都会有一个唯一的Service Identifier,你可以看成是变量名称(Variable Name) ,不要跟Contract Identifier搞混了, Contract Identifier的格式会是像这样: / [year]/[month]/[name].html (这样你知道刚刚对话框要你填日期以及Organization Domain是要干啥用了吧),它才是这个DSS Service的功能名称,你可以看成是类别名称(Class Name).每个DSS都会有一个状态(State),也会有一堆程序代码(Service Handlers)负责对外沟通(Main Port) ,还可以有通知(Notifications) ,然后可以有协同运作的Service (Partners)这几大块.完成以后你会看到Visual Studio帮你生了一个项目像是这样:其中DSSService_HelloWorldType.cs放的是宣告的程序代码, DSSService_HelloWorld.cs则是主体程序代码(当然事后你可以乱改..)为了完成Hello World,我们来把这个DSS的State加上一个字符串的数据成员(Data Member)吧,你可以在DSSService_HelloWorldTypes.cs当中找到下面这段程序代码:/// <summary> ///DSSService_HelloWorld state ///</summary>[DataContract]public class DSSService_HelloWorldState{}我们加上一个字符串成员的宣告如下:/// <summary> ///DSSService_HelloWorld state[DataContract]public class DSSService_HelloWorldState{[DataMember]public string StrData { get; set; }}每个DSS Service在启动的时候,会呼叫Start()这个函式,所以你在DSSService_HelloWorld.cs当中可以找到它: /// <summary> ///Service start ///</summary>protected override void Start(){// // Add service specific initialization here //base.Start();}现在我们加上_state.StrData = "Hello World";如下:/// <summary> ///Service startprotected override void Start(){// // Add service specific initialization here //base.Start();_state.StrData = "Hello World";}Ok,现在我们完成一个DSS Service,这个Service的状态有一个StrData ,而启动以后会放入"Hello World",透过VS 2008建置以后,它自动会放在你的VPL bin目录下面,像是这样:所以你打开VPL ,就可以看到Services 多了一个DSSService_HelloWorld,把它拖来到Diagram当中,连上SimpleDialog,你会从DSSService_HelloWorld看到Get-Success 联机(这表示你想要取得该DSS Service的状态(state)),连接设定如下:现在你的VPL程序如下:好啦,一周后我们又回到了Hello World ...-->2008/12/25 01:37|阅读数: 1045 |我要推荐| 8 Comments | |订阅DotBlogs Tags: Robotics关连文章•[Robotics Studio]改良自走型机器车[III] --Day7• [Robotics Studio]改良自走型机器车[II] --Day6• [Robotics Studio] MSRS概观(Overview) --Day5• [Robotics Studio]自走型机器车--Day4• [Robotics Studio]介绍Activity --Day3• [Robotics Studio]开始玩机器人啦--Day2• mxymxy 2009/1/22下午03:49回复# re: [Robotics Studio] Hello World Again! (DSS Service version) --Day8我有Visual Studio 2008 (or Express Edition) ,但我不可以在新增项目当中看到Microsoft Robotics Express,为什么• laneser 2009/1/22下午06:17回复# re: [Robotics Studio] Hello World Again! (DSS Service version) --Day8to mxymxy :我的顺序是:先安装VS 2008 ,再安装robotics developer studio .• mxymxy 2009/1/22下午08:09回复# re: [Robotics Studio] Hello World Again! (DSS Service version) --Day8重装了一遍,成了,不过只有C#,不是能用C++吗?谢谢• laneser 2009/1/23下午12:00回复# re: [Robotics Studio] Hello World Again! (DSS Service version) --Day8to mxymxy : Express 只有C# , Standard版本才能用C++,或其它语言(希望M$下次能发发善心)• Comix 2009/1/30上午01:03回复# re: [Robotics Studio] Hello World Again! (DSS Service version) --Day8Laneser你好!我是一名初学者,不知用C#编写DSS SERVICE需要多少C#基础啊?谢谢!祝新春快乐!• laneser 2009/1/31下午12:38回复# re: [Robotics Studio] Hello World Again! (DSS Service version) --Day8to Comix :我觉得C#写DSS还算有点深度,所以,个人建议有以下基础后再学比较不会遇到困难(由浅至深):1.基本的C#观念2.泛型(Generic)3.多执行绪(Multi-thread)4. Enumerator (yield),以及因为Enumerator所造成的deferred execution概念不过,如果很有兴趣,也可以摸索前进,倒不一定要循规蹈矩,只要有热情跟谦逊,遇到问题就想办法了解并解决就好啰.DSS以及CCR都有点算是新的工具用来解决以前遇到的问题,所以对于初学者或是老手,都算是从头学起,顶多是老人比较占一点点优势(对于旧问题),新手的优势就是没有包袱(就像张三丰教太极,你已经忘光了XD)...• tinghoo 2009/2/25上午04:37回复# re: [Robotics Studio] Hello World Again! (DSS Service version) --Day8“”请好,请问那个新增专案是在哪,我找不到我现在把所有的都卸载掉,那具体应该都安装哪些呢,顺序?麻烦你了• tinghoo 2009/2/25上午05:53回复# re: [Robotics Studio] Hello World Again! (DSS Service version) --Day8我知道了,原来是因为大陆的台湾的翻译不一样,麻烦了。

第24天Microsoft Robotics Developer Studio中文教程--DSS System Services

第24天Microsoft Robotics Developer Studio中文教程--DSS System Services

這個我們之前玩過了, 可以透過它來產生其他的DSS Service, 還可以看到系統存在的DSS Service, 正在執行的DSS Service, 以及可以手動停止DSS Service.第三個是Service Directory :透過它, 可以知道目前正在執行的DSS Service , 以及它們的Partners.(不過寫DSS Service 的人也可以故意不跟它註冊, 據說這樣就不會列在這個表當中)接著是Debug and Trace Messages , 這個是由Console Output Service 來執行的:你的 DSS Service 自然也可以透過它來輸出debug 訊息歐.. Manifest Load Results , 是由Manifestloaderclient 執行的這裡可以看到Manifest loader service (另一個DSS System Service)載入manifest 的結果, Security Manager , 是由Security Manager Service 執行的:主要就是讓你可以控制這個DSS Node 的權限, 像是連上此Node 是否需要認證, 以及一些角色的設定等等, 如果你連不到某個DSS Node, 要先看看該DSS Node 的Security Manager 是否有設定正確才是.Resource Diagnostics Service 負責顯示這個DSS Node 目前正在運作的每個service 的資料狀態(portmessage queue), 以及執行中的task dispatcher其他不在表列當中, 但是也是DSS System Services 的, 有Consturctor Service : 提供給其他Service 用來Create Service 的介面, 通常Manifest loader service 就利用它.Mountpoint service :其他DSS Service 可以透過Mount point service 來存取檔案, 但只限於安裝目錄下的部分目錄. Constract Directory Service : 用來揭露哪些目錄存放DSS Service 的執行檔案:Embedded Resources Services : 用來揭露DSS 內嵌的資源:Subscription Manager Service : 用來協助註冊通知的Service, 雖然是DSS System Service , 但是它通常是每個Service 自己有一份實體,只是用來協助DSS Service 處理註冊通知相關事宜, 免得大家(每一個DSS Service)都要寫一份code .Partner Manager Service : 類似 Subscription Manager service, 也是所謂的helper service , 用來處理partner service 相關處理事宜.以上, 就是全部的 DSS System Service (目前這個RDS 2008 版本啦, 下一版可能會更多?!).-->。

第3天Microsoft Robotics Developer Studio中文教程--介绍 Activity

第3天Microsoft Robotics Developer Studio中文教程--介绍 Activity

現在你已經有一個自訂的活動了, 看起來就像是這樣:對它點兩下, 你會進入編輯畫面,讓我們回到剛剛的Diagram , 把原本中間的一堆元件複製過來這個RobotControl Activity. 如下:現在你看到一堆驚嘆號了, 這代表有些小問題需要解決.移動到每一個小驚嘆號, 都會告訴你發生了甚麼問題, 首先, 我們要先宣告這個活動的介面,也就是定義這個活動的輸出以及輸入. 點擊上方的紅色編輯紐, 或者使用下拉選單的Edit/ Actions and Notifications, 你會看到這個對話框:主要分為兩大區塊, Actions 代表你可以定義的反應, 所謂的Action, 是指需要輸入一個訊息, 然後該Activity 會經過一些處理以後(包括做了一些整體環境上的改變), 最後吐出一個訊息, 而Notifications 就比較簡單, 是自動自發的吐出訊息, 不需要輸入訊息. 所以通常一個流程的最前面的元件往後吐出訊息的是Notification.再回到Actions, 我們可以看到下方有三排Add,Delete, 由左至右分別代表你新增刪除定義的Actions, 新增刪除輸入的訊息組合內容, 新增刪除輸出的訊息組合內容. 每一個Action 你都可以定義個別的輸出入內容, 而且每一個Action 都是一個獨立的編輯元件畫面歐.讓我們定義一個Action, 取名為ControlDirection, Input values 需要一個PressButton, Type 是String, Output values 則是LeftDriverPower, RightDriverPower, Type 都是double, 如下:之後, 我們把左邊的輸入拉到原本的Calculate 這個元件.為了要統一輸出, 所以我們還要多拉一個Join, 把"Stop", "Fowards", "Backwords" 產生出來的訊息經由Merge 後再一次Join, 一樣在Join 裡面填入left, right , 如下:然後把這個Join 輸出給"Left", "Right" 的 Merge,最後把這個Merge 輸出給Result, 整體的流程就像下面這樣:當你把Merge 的結果輸出給Result 時, 會跳出Data Connections 對話框, 此時你要指定輸出的LeftDriverPower, RightDriverPower 為何,因為透過Merge, Visual Programming Language Express Edtion 無法計算出正確的下拉選單給你選(你只能選value), 但是其實要輸入的值應該是value.left, value.right (因為Merge 之前的訊息是Join 吐出來的), 所以你要勾選下方的Edit Values Directly, 自己輸入正確值(但系統會提示你),如下:這樣你就完成了一個Activity (其中的一個Action) 的定義囉!讓我們回到原本的Diagram, 刪除那些被你複製到Activity 當中的元件, 改用這個Activity 取代,當你把DirectionDialog 的Notifications 拖到這個RobotControl 的Activity 時, 會出現Connections 對話框,我們當然選擇ButtonPress , 如下:接著出現Data Connections 對話框, 要選而當你把這個RobotControl Activity 的輸出丟給GenericDifferentialDrive 的時候,又出現Connections 對話框, 輸出要選SetDrivePower,Data Connections 對話框設定如下:現在整體的元件流程就像下圖:這樣看起來清爽多了吧.那我們之前複製的一個分身GenericDifferentialDrive 也就不需要了.不過, 暫且不要刪掉它, 還記得昨天你玩車子的時候, 按下去就一直跑了, 直到按Stop, 是有點不方便.現在我們改為放開就停止, 這樣還不錯玩.所以我們再複製一個DirectionDialog (請注意, 它還是該DirectionDialog 的分身囉),然後把Notification 直接拖到另一個分身GenericDifferentialDrive,在Connections 對話框設定ButtonRelease 給SetDrivePower,在Data Connections 對話框設定兩個值都是0這樣你的整體元件流程如下:好啦, 可以試玩看看是不是好多了? 比較不會翻車囉?撞到東西還是會翻啦XD有了自訂Activity, 就像是可以自己定義積木, 我們就可以邁向更複雜的人生啦...(啊?!)-->。

第1天Microsoft Robotics Developer Studio中文教程

第1天Microsoft Robotics Developer Studio中文教程

然後我們要做一些設定, 把Data 的類別改為String,
, 然後在中間填入Hello World , 變成如下的畫面.
接著, 我們把這個資料輸出到一個Service, 選擇左邊的Service, 找到Simple Dialog 這個元件.如果你覺得不好找, 可以在Find Service 當中輸入Simple , 如下:
這樣就只會過濾到剩下有Simple 文字的元件,
就可以容易找到Simple Dialog 這個元件.
把Simple Dialog 拖到右邊的Diagram 當中.
現在我們要做最後一步啦, 把這兩個元件串起來, 點選Data 元件的右邊(Outgoing Response) , 拖到Simple Dialog,
就會彈出Connections (Simple Dialog 的)對話框啦, From 沒得挑, 因為就是DataValue, To 我們選"AlertDialog",
點選OK , 又彈出Data Connections 的對話框, 這次我們要把Value 下拉, 選出value 這個值.
再一次點選OK,
噹噹! 我們寫完了Hello World 程式了.
雖然沒啥大用處, 但是還是可以執行看看囉,
執行之前Visual Programming Language Express Edition 會要求你存檔, 執行結果如下:
OK. 很簡單的程式, 所以我相信應該沒甚麼問題的.
一步一步來, 這樣很快就可以玩到機器人了?!(應該吧)。

第27天Microsoft Robotics Developer Studio中文教程--CameraSprite in VSE

第27天Microsoft Robotics Developer Studio中文教程--CameraSprite in VSE

newRobot.InsertEntity(sumoCam);恩, 就這樣, 雙方的機器人上面都有一個攝影機的畫面啦!決鬥過程也都可以看到...11. public string FontFamily12. {13. get { return _fontFamily; }14. set { _fontFamily = value; }15. }16.17. /// <summary>18. /// The font size of the font to use19. /// </summary>20. [DataMember]21. public float FontSize22. {23. get { return _fontSize; }24. set { _fontSize = value; }25. }26.27. /// <summary>28. /// Default constructor29. /// </summary>30. public TextSprite() { }31.32. /// <summary>33. /// Initialization constructor34. /// </summary>35. /// <param name="width"></param>36. /// <param name="height"></param>37. /// <param name="textureWidth"></param>38. /// <param name="textureHeight"></param>39. /// <param name="pivot"></param>40. /// <param name="initialPos"></param>41. /// <param name="family"></param>42. /// <param name="fontSize"></param>43. public TextSprite(string text, float width, float height, int textureWidth, int textureHeight,SpritePivotType pivot, Vector3 initialPos, string family, float fontSize)44. : base(width, height, textureWidth, textureHeight, pivot, initialPos)45. {46. _text = text;47. _fontFamily = family;48. _fontSize = fontSize;49. }50.51. /// <summary>52. /// Initialize53. /// </summary>54. /// <param name="device"></param>55. /// <param name="physicsEngine"></param>56. public override void Initialize(Microsoft.Xna.Framework.Graphics.GraphicsDevice device,PhysicsEngine physicsEngine)57. {58. try59. {60. InitError = string.Empty;61. Font nameFont = new Font(_fontFamily, _fontSize);62. base.Initialize(device, physicsEngine);63. Bitmap target = GetBitmap();64. Graphics g = Graphics.FromImage(target);65. g.FillRectangle(Brushes.DarkBlue, 0, 0, target.Width, target.Height);66. StringFormat nameFormat = new StringFormat();67. nameFormat.Alignment = StringAlignment.Center;68. nameFormat.LineAlignment = StringAlignment.Center;69. g.DrawString(_text, nameFont, Brushes.White, new Rectangle(0, 0, target.Width,target.Height), nameFormat);70. SetBitmap(target);71. }72. catch (Exception ex)73. {74. HasBeenInitialized = false;75. InitError = ex.ToString();76. }77. }78.}public class TextSprite : SpriteEntity{private string _fontFamily;private float _fontSize;private string _text;/// <summary>/// The font family name of the font to use/// </summary>[DataMember]public string FontFamily{get { return _fontFamily; }set { _fontFamily = value; }}/// <summary>/// The font size of the font to use/// </summary>[DataMember]public float FontSize{get { return _fontSize; }set { _fontSize = value; }}/// <summary>/// Default constructor/// </summary>public TextSprite() { }/// <summary>/// Initialization constructor/// </summary>/// <param name="width"></param>/// <param name="height"></param>/// <param name="textureWidth"></param>/// <param name="textureHeight"></param>/// <param name="pivot"></param>/// <param name="initialPos"></param>/// <param name="family"></param>/// <param name="fontSize"></param>public TextSprite(string text, float width, float height, int textureWidth, int textureHeight, SpritePivotType pivot, Vector3 initialPos, string family, float fontSize): base(width, height, textureWidth, textureHeight, pivot, initialPos){_text = text;_fontFamily = family;_fontSize = fontSize;}這個TextSprite 比原本的EntityNameSprite 好用多了, 不但可以顯示任何字(要考慮字型), 還可以不限定要加在某個Entity 當中(直接加到VSE).(因為原本的 EntityNameSprite 一定要掛在某個Entity 下面, 用來顯示該Entity 的名稱)-->。

Microsoft Robotics Developer Studio中文教程--初体验

Microsoft Robotics Developer Studio中文教程--初体验


之后就是下一步之类的动作,不需要大脑的~
安装过程中,有看到他在装 DirectX 9c,这应该是模拟环境所必须的,因为模拟时要做 3D 显示。
到安装完成的时间,花了将近十几分钟吧... 看起来装了不少东西。 学习资源 以「原典」为优先,目前找到的有底下几个,先一步一步来吧~ 虽然很想赶快弄点东西来玩,不过还是要先把基础知识搞清楚 RDS Overview : 底下 See Also 的部分有很多后续学习的资源,之后在花些时间来看一看,英文挺多的... XD 了解 Microsoft Robotics Studio : 看起来是上面的简体中译版,不过一些连结都坏了,可以跟英文互相对照
[Robotics Studio x1] 初体验 编辑整理< 杜毓聪 duyucong@ >
从微软下载中心下载 Microsoft Robotics Developer Studio 2008 Express Edition,如网站所说,这是提供给 Developer 跟 Hobbyist 的免费版本,另外还有更强的 Standard Edition,但是价格令人乍舌,通常是商业应用或实际 开发机械人的公司才会玩这个吧。不过 Standard Edition 有提供给学术用途就是了。 Express Edition 下载还有分 Offline 版跟网路版,网路版在安装时需要网路抓其他东西,Offline 版就是应有尽有,不 过档案也大了许多,共三百多 MB。 安装 开始安装之后,会先检查你的环境,根据我的检查结果,还需要安装这四个东西 Microsoft Visual C++ 2008 SP1 Redistributable Package (x86) : 应该算是补充包吧 Microsoft XNA Framework 2.0 : 主要开发程式所利用的 Framework NVIDIA PhysX System Software : 是用来模拟的 3D 虚拟环境,用来测试应用程式的 Microsoft CCR and DSS Runtime 2008 : CCR 与 DSS 的执行期档案

Microsoft Robotics Studio中文教程1

Microsoft Robotics Studio中文教程1

目录i目录第一章绪论 (1)1.1 机器人开发平台现状 (1)1.2 Microsoft Robotic Studio 概述 (3)1.3 Microsoft Robotic Studio的组成 (4)1.2.1 Visual Programming Language(VPL) (4)1.2.2 Microsoft DSS Manifest Editor(DDSME) (5)1.4 本文主要研究成果与内容安排 (5)第二章 VPL的组件与功能 (7)2.1 数据类组件 (7)2.1.1 Variable(变量组件) (7)2.1.2 Calculate(计算组件) (7)2.1.3 Data(数据组件) (8)2.1.4 Math Function(数学组件) (8)2.2 逻辑类组件 (9)2.2.1 If组件 (9)2.2.2 Switch组件 (9)2.2.3 Join组件 (9)2.2.4 Merge组件 (10)2.3 输出类组件 (10)2.3.1 Simple Dialog组件 (10)2.3.2 Flexible Dialog组件 (11)2.3.3 Log组件 (12)2.3.4 TexttoSpeechTSS组件 (12)2.4 通用器件 (13)2.4.1 Generic Contact Sensors (13)2.4.2 Sick Laser Range Finder (14)2.4.3 Generic Differential Driver (14)目录ii2.5 输入类器件 (15)2.5.1 Desktop Joystick组件 (15)2.5.2 Direction Dialog组件 (15)2.5.3 Game Controller组件 (16)2.5.4 Webcam组件 (16)2.6 定义类组件 (16)2.7 本章小结 (17)第三章机器人运动规划 (19)3.1 避障规划(避障行为) (19)3.1.1 基于接触传感器的避障实现 (19)3.1.2 测距传感器的避障实现 (21)3.2 运动规划中会出现的问题 (22)3.2.1 抖动问题 (22)3.2.2 峡谷效应问题 (24)3.3 本章小结 (25)第四章基于Microsoft Robotic Studio的机器人避障的实现 (27)4.1 采用模型的选择 (27)4.2 基于激光测距传感器的避障程序实现 (30)4.3 基于接触传感器的避障程序实现 (35)4.4 本章小结 (38)第五章虚拟环境的实现与测试 (39)5.1虚拟环境简介 (39)5.2 虚拟环境的组成 (40)5.3 试验环境的设定 (41)5.4 机器人避障在虚拟环境中的实测 (44)第六章总结与展望 (47)6.1 本文总结 (47)6.2 下一步的试验方向 (48)致谢 (49)参考资料 (50)第一章绪论 1第一章绪论当今,随着低成本开发平台变得日益唾手可得,人们将机器人用于教育与最终应用的机会也在不断增加。

第28天Microsoft Robotics Developer Studio中文教程--Pursuit Camera

第28天Microsoft Robotics Developer Studio中文教程--Pursuit Camera

這個 code 就是產生一個 PursuitCameraEntity (給他機器人的名稱, 它就會開始追蹤該機器人), 討厭的地方就是它根本沒有預設名稱啊, 所以你要給一個名稱, 不然會沒辦法加入 VSE 當中的... 那麼, 加了這樣的 code , 我們的 VSE 也就出現一個 PursuitCameraEntity 囉.
[Robotics Studio] Pursuit Camera -- Day28
编辑整理<杜毓聪 duyucong@ > 之前在玩迷宮機器人的時候, 常常要一邊移動機器人, 一邊移動攝影機 (Camera) 畫面, 很是累人... 尤其是建造了那麼複雜的迷宮之後, 移動攝影機就更是累人了... 在解決問題之前, 先看看 Robotics Developer Studio 原本就提供的範例, 這樣我們就知道有甚麼好的解決辦法了. 打開 VPL (Visual Programming Lanaguage), 點選 File, Open, 找到 RDS 安裝目錄下的 samples\VplExamples\DriveSimFourByFour 下面, 打開這個專案:
我不是指翻車啦, 是攝影機會追著車子跑...這種攝影機就是我們玩遊戲常看的攝影機, 這樣才像樣嘛...
ok, 打完收工, 那個 4x4 的車子已經領便當了... 甚麼? 你說問題還沒解決? 這就是我看那個 MsrsUserGuideExpress.chm 討厭的地方, 問題都沒解決就結束了.. 最後只有這段話 : "The Pursuit Camera consists of two components: a simulation enstart the service to use the camera in the Simulator, but your application must programmatically add a Pursuit Camera entity. ... By default, the camera entity name is PursuitCamera" 意思就是叫你自己生一個 PursuitCamera Entity 就好了... 還誤導我一句, 有個預設名稱叫做 PursuitCamera ... (事實上我最後只能這樣解釋: 他是說這個範例裡面的 PursuitCamera 預設值...) 好吧, 讓我告訴各位我是怎麼做的: 1. 在建造迷宮以及機器人那個專案當中, 參考 PursuitCamera.Y2008.M04.dll (在 RDS 安裝目錄的 bin 下面) 2. using 加上 using pursuitcamera = Microsoft.Robotics.Entities.PursuitCamera; 3. 產生機器人以後, 改一下函式, 把機器人的名稱傳回來, 然後加上下面的 code : view plaincopy to clipboardprint? 1. string robotname = AddPioneer3DX(new Vector3(1.5f, 0.1f, 0f), -90); 2. 3. pursuitcamera.PursuitCameraEntity pcamera = new pursuitcamera.PursuitCameraEntity(robotname); 4. = "PursuitCameraEntity"; 5. 6. SimulationEngine.GlobalInstancePort.Insert(pcamera); string robotname = AddPioneer3DX(new Vector3(1.5f, 0.1f, 0f), -90); pursuitcamera.PursuitCameraEntity pcamera = new pursuitcamera.PursuitCameraEntity(robotname); = "PursuitCameraEntity"; SimulationEngine.GlobalInstancePort.Insert(pcamera);

第15天Microsoft Robotics Developer Studio中文教程--P3DX[III] - 继续画地图

第15天Microsoft Robotics Developer Studio中文教程--P3DX[III] - 继续画地图
public class ScanMapCommand : Update<ScanMapData, PortSet<DefaultUpdateResponseType, Fault>> { }
public class UpdateDriveDistance : Update<drive.DriveDistanceRequest, PortSet<DefaultUpdateResponseType, Fault>> { }
[DataContract] public class ScanMapData {
[DataMember] public double ForwardScan; [DataMember] public double RotateScan; }
然後, 為了這個需求, 我們還要在收到指令後, 算出下一次 ScanMap 在地圖當中的位置, 所以在狀態當中新增
2. Activate(Arbiter.Receive<drive.RotateDegrees>(true, _driveNotify, update => _mainPort.Post(new UpdateDriveRotate() { Body = update.Body })));
Activate(Arbiter.Receive<drive.DriveDistance>(true, _driveNotify, update => _mainPort.Post(new UpdateDriveDistance() { Body = update.Body }))); Activate(Arbiter.Receive<drive.RotateDegrees>(true, _driveNotify, update => _mainPort.Post(new UpdateDriveRotate() { Body = update.Body })));

第18天Microsoft Robotics Developer Studio中文教程--透过 Web Interface 操控 DSS

第18天Microsoft Robotics Developer Studio中文教程--透过 Web Interface 操控 DSS
/5 09:13| 閱讀數 : 525 | 我要推薦 | One Comment | | 訂閱 DotBlogs Tags: Robotics
關連文章
• • • • • • • • • •
[Robotics [Robotics [Robotics [Robotics [Robotics [Robotics [Robotics [Robotics [Robotics [Robotics
在左邊的 System Services 你可以發現 Control Panel , 點選它, 你會看到目前系統中所有的 DSS Service , 如下:
找到 TextToSpeech (你可以在 Search 當中輸入 text, 就會過濾列出有 text 的, 如下)
看到右邊有個 Create 按鈕, 按下它, 就會生成一個 TTS Service, (按下它之後再 Refresh, 或是重新點一次 control panel, 就會看到生出來的 Service)
回應
jiguo 2009/5/3 下午 06:32 回覆 # re: [Robotics Studio] 透過 Web Interface 操控 DSS -- Day18 我运行了 run Dss node,但是没有出现上述右侧显示的界面。不知道为什么原因,controlpanel 点击,也没有出现应 有的界面。希望解答一下。谢谢。
[Robotics Studio] 透過 Web Interface 操控 DSS -- Day18
编辑整理<杜毓聪 duyucong@ > 現在開始簡單課程, 以免曲高和寡 (講難聽點是偷懶吧?!) 經過了十幾天的 RDS 介紹, 相信你對 DSS 一定不陌生, 而 DSS Service 都可以用 Web 的介面 (Http protocol) 來 操控的. 就舉 TextToSpeech 這個 DSS Service 為例: 想 要啟動 DSS Service Host (就是每次 VPL 啟動時, 或是 DSS Service 在 VS 2008 啟動時) , 你可以用開始程式 集當中的 Microsoft Robotics Developer Studio 2008 Express 當中的 Run DSS Node (內容就是 "C:\Users\lane\Microsoft Robotics Dev Studio 2008 Express\bin\DssHost32.exe" /p:50000 /t:50001 /m:"samples\config\UriLauncher.manifest.xml") 之後你會發現啟動 DssHost32.exe, 而且啟動瀏覽器到 http://localhost:50000/

第26天Microsoft_Robotics_Developer_Studio中文教程--继续修改迷宫, 加上机器人

第26天Microsoft_Robotics_Developer_Studio中文教程--继续修改迷宫, 加上机器人

[Robotics Studio] 继续修改迷宫, 加上机器人-- Day262009/1/16 17:51 | 阅读数: 4829 | 我要推荐 | 3 Comments | 订阅嗯,之前的迷宫产生程式有点小bug,就是在分割房间的时候,如果产生的墙壁刚好挡住之前挖开的洞,这个迷宫就有可能会不通...所以加上一点小修改来弥补这样的错误,最后整个MazeEntity的程式如下(我直接把注解写在code 当中了):001 using System;002 using System.Collections.Generic;003 using ponentModel;004 using r.Core;005 using Microsoft.Dss.Core.Attributes;006 using Microsoft.Dss.ServiceModel.Dssp;007 using Microsoft.Dss.ServiceModel.DsspServiceBase;008 using W3C.Soap;009 using submgr = Microsoft.Dss.Services.SubscriptionManager;010 using engine = Microsoft.Robotics.Simulation.Engine.Proxy;011 using Microsoft.Robotics.Simulation.Engine;012 using Microsoft.Robotics.Simulation.Physics;013 using Microsoft.Robotics.PhysicalModel;014015016 namespace MazeGenerator017 {018 public class MazeEntity : MultiShapeEntity019 {020 /// <summary>021 /// Default constructor022 /// </summary>023 public MazeEntity() { }024025 /// <summary>026 /// Initialization constructor027 /// </summary>028 /// <param name="shape"></param>029 /// <param name="initialPos"></param>030 public MazeEntity(Vector3 initialPos,byte[,]blocks,float mazeheight,float blocksize)031 {032 for(int x = 0; x < blocks.GetLength(0); x++) 033 {034for(int y= 0; y <blocks.GetLength(1); y++)035 {036 if(blocks[x,y] == 0) 037 continue; 038039 var boxshape=new BoxShape(04 0new BoxShapeProper ties(04 1100,// mass in kilograms.04 2new Pose(new Vector 3(initialPos.X + x * blocksize, initialPos.Y + mazeheight / 2, initialPos.Z - y*blocksize)),// relative pose04 3new Vector3(blocks ize, mazeheight, blocksize)));04404 5this.BoxShapes.Add(boxsha pe);// dimensions046 }047}048049 this.State.MassDensity.Mass=blocks.GetLength(0)*blocks.GetLength(1)*100; 050 }051052 public static byte[,]GenerateMaze(int width,int height)053 {054 byte[,] result =new byte[width, height]; 055 Random r =new Random();056 for(int x = 0; x < width; x++)057 for(int y = 0; y < height; y++)058 result[x, y] = (byte)(((x== 0) || (y == 0) || (x == width - 1) || (y == height - 1)) ? 1 : 0); 059060 // dig a hole of left-top, and right-down 061 result[0, 1] = 0;062 result[width - 1, height - 2] = 0;063064 splitMazeChamber(r, result, 0, 0, width - 1,height - 1);065066 return result; 067 }068069 /// <summary>070 /// 将一个房间切割为迷宫, 前提是这个房间四周都是墙壁, 但是会有一些通道, 连到其他房间071 /// </summary>072 /// <param name="r"></param>073 /// <param name="maze"></param> 074 /// <param name="left"></param> 075 /// <param name="top"></param> 076 /// <param name="right"></param> 077 /// <param name="bottom"></param>078 private static void splitMazeChamber(Randomr,byte[,] maze,int left,int top,int right,int bottom)079 {080 int wallX = 0;081 if(right - left > 3)082 wallX = r.Next(left + 2, right - 1); 083084 int wallY = 0;085 if(bottom - top > 3)086 wallY = r.Next(top + 2, bottom - 1); 087088 // 停止条件- 没得切割房间089 if((wallX <= 0) && (wallY <= 0))090 return;091092 // 建造墙壁来隔开房间093 if(wallX > 0)094 {095 for(int i = top + 1; i < bottom; i++) 096 maze[wallX, i] = 1;097098 // 假如这道墙壁刚好盖在外部的通道, 就拆掉一格墙壁099 if(maze[wallX, top] == 0)100 maze[wallX, top + 1] = 0; 101 if(maze[wallX, bottom] == 0)102 maze[wallX, bottom - 1] = 0; 103 }104105 if(wallY > 0)106 {107 for(int i = left + 1; i < right; i++) 108 maze[i, wallY] = 1;109110 // 假如这道墙壁刚好盖在外部的通道, 就拆掉一格墙壁111 if(maze[left, wallY] == 0)112 maze[left + 1, wallY] = 0; 113 if(maze[right, wallY] == 0)114 maze[right - 1, wallY] = 0; 115 }116117 // 打通各个房间, 然后继续切割每个房间118 if((wallX > 0) && (wallY > 0))119 {120 List<KeyValuePair<int,int>>holes =new List<KeyValuePair<int,int>>();12holes.Add(new KeyValuePair<int,in1 t>(wallX, r.Next(top + 1, wallY - 1)));12 2holes.Add(new KeyValuePair<int,in t>(wallX, r.Next(wallY + 1, bottom - 1)));12 3holes.Add(new KeyValuePair<int,in t>(r.Next(left + 1, wallX - 1), wallY));12 4holes.Add(new KeyValuePair<int,in t>(r.Next(wallX + 1, right - 1), wallY));125 holes.RemoveAt(r.Next(0, 4));126holes.ForEach(hole=>maze[hole.Key, hole.Value] = 0); 127128 splitMazeChamber(r, maze, left,top, wallX, wallY);129 splitMazeChamber(r, maze, wallX,top, right, wallY);130 splitMazeChamber(r, maze, left,wallY, wallX, bottom);131 splitMazeChamber(r, maze, wallX,wallY, right, bottom);132 }133 else if(wallX > 0) 134 {135 maze[wallX, r.Next(top + 1, bottom- 1)] = 0; 136137 splitMazeChamber(r, maze, left,top, wallX, bottom);138 splitMazeChamber(r, maze, wallX,top, right, bottom);139 }140 else if(wallY > 0) 141 {142 maze[r.Next(left + 1, right - 1),wallY] = 0; 143144 splitMazeChamber(r, maze, left,top, right, wallY);145 splitMazeChamber(r, maze, left,wallY, right, bottom);146 }147 }148 }149 }上面的程式就可以产生不会卡死的迷宫了,接下来, 要放机器人上去, 因为code 不少, 我就直接把注解写在code 当中让大家看啰: 001 /// <summary>002 /// 产生一个名字后面带有Guid, 这样可以避免与其他名称重复003 /// 因为VSE 当中的Entity 名称是不可以重复的.004 /// </summary>005 /// <param name="name"></param>006 /// <returns></returns>007 private string CreateNamePlusGuid(string name)008 {009 return name +"_"+ Guid.NewGuid().ToString();010 }011012 /// <summary>013 /// 产生一个虚拟机器人Pioneer3DX 到VSE 当中014 /// </summary>015 /// <param name="position"></param>016 /// <param name="angle">面对的角度</param>017 private void AddPioneer3DX(Vector3 position,float angle) 018 {019 Pioneer3DX robotBaseEntity=CreatePioneer3DXMotorBase(position);020021 // 产生虚拟SickLRF 放入机器人当中022 robotBaseEntity.InsertEntity(CreateLaserRangeFinder()); 023024 // 产生虚拟的碰撞侦测器放入机器人当中025 robotBaseEntity.InsertEntity(CreateBumperArray());026027 // 产生虚拟的WebCam 放入机器人当中028 robotBaseEntity.InsertEntity(CreateRobotCamera());030 // 旋转角度031robotBaseEntity.State.Pose.Orientation = 032 TypeConversion.FromXNA(xna.Quaternion.CreateFromAx isAngle( new xna.Vector3(0, 1, 0), ( float )(( double )angle * Math.PI / ( double )180)));033 034 // 将这个Entity 放入VSE 当中035 SimulationEngine.GlobalInstancePort.Insert(robotBaseEntity);036037 }038039 /// <summary>040 /// 产生SimulatedDifferentialDrive 当中已经建立好的Pioneer3DX 虚拟机器人041 /// </summary>042 /// <param name="position"></param>043 /// <returns></returns>044 private Pioneer3DX CreatePioneer3DXMotorBase(Vector3 position)045 {046 Pioneer3DX robotBaseEntity = new Pioneer3DX(position);047 = CreateNamePlusGuid( "P3DXMotorBase" );048049 // 指定VSE 当中的Entity 来启动SimulatedDifferentialDrive 服务050 drive.Contract.CreateService(ConstructorPort, " http://localhost/ " + ,051 Microsoft.Robotics.Simulation.Partners.CreateEntityPartner(052 " http://localhost/ " +)053 );054055 return robotBaseEntity;056 }058 /// <summary>059 /// 产生虚拟的Sick LRF060 /// </summary>061 /// <returns></returns>062 private LaserRangeFinderEntity CreateLaserRangeFinder()063 {064 // 产生Sick LRF Entity, 放在附加物件的中心上方30 公分(0.3 公尺) 处065 LaserRangeFinderEntity laser = new LaserRangeFinderEntity(066 new Pose( new Vector3(0, 0.30f, 0)));067068 =CreateNamePlusGuid( "P3DXLaserRangeFinder" );069 070 // 产生一个虚拟的LRF 服务, 指定VSE 当中的Entity071 lrf.Contract.CreateService(072 ConstructorPort, " http://localhost/ " + ,073 Microsoft.Robotics.Simulation.Partners.CreateEntityPartner(074" http://localhost/ " + )); 075 return laser;076 }077078079 /// <summary>080 /// 产生虚拟的前后碰撞侦测器081 /// </summary>082 /// <returns></returns>083 private BumperArrayEntity CreateBumperArray()084 {085 // 产生前后的Bumper Entity086 BoxShape frontBumper = new BoxShape(087 new BoxShapeProperties( "front" ,088 0.001f,089 new Pose(new Vector3(0, 0.05f, -0.25f)), 090 new Vector3(0.40f, 0.03f, 0.03f)091 )092 );093094 BoxShape rearBumper =new BoxShape(095 new BoxShapeProperties("rear",096 0.001f,097 new Pose(new Vector3(0, 0.05f, 0.25f)), 098 new Vector3(0.40f, 0.03f, 0.03f)099 )100 );101102 // 物理引擎(Physics Engine) 必须要指定这个Entity 启动碰撞通知, 这样虚拟服务才会运作正常103 frontBumper.State.EnableContactNotifications =true; 104 rearBumper.State.EnableContactNotifications =true; 105106 BumperArrayEntity107 bumperArray=new BumperArrayEntity(frontBumper,rearBumper); 108109 =CreateNamePlusGuid("P3DXBumpers"); 110111 // 指定Entity 来启动虚拟服务112 bumper.Contract.CreateService(11 3ConstructorPort,"http://localhost/"+ ,11 4Microsoft.Robotics.Simulation.Partners.CreateEntit yPartner(115 "http://localhost/"+ )); 116 return bumperArray;117 }118119 /// <summary>120 /// 产生虚拟的摄影机121 /// </summary>122 /// <returns></returns>123 private CameraEntity CreateRobotCamera() 124 {125 // 指定解析度126CameraEntity cam=new CameraEntity(320, 240,CameraEntity.CameraModelType.AttachedChild);127 = CreateNamePlusGuid("robocam");128 // 放在机器人的上方50 公分处129 cam.State.Pose.Position =new Vector3(0.0f, 0.5f, 0.0f); 130131 // 需要设定这个来配合Simulated webcam service132 cam.IsRealTimeCamera =true;133134 // 指定Entity 来启动虚拟服务135 simwebcam.Contract.CreateService(136 ConstructorPort,"http://localhost/"+ ,13 7Microsoft.Robotics.Simulation.Partners.CreateEntit yPartner(138"http://localhost/"+ ) 139 );140141 return cam;142 }143144 /// <summary>145 /// 产生虚拟的LEGO-Nxt Tribot 到VSE 当中146 /// </summary>147 /// <param name="position"></param>148 private void AddLegoNxtRobot(Vector3 position)149 {150 // 产生LEGONXTTribot151 LegoNXTTribot robotBaseEntity=CreateLegoNxtMotorBase(position); 152153 // 加入前方的碰撞感应器154 robotBaseEntity.InsertEntity(CreateLegoNxtBumper());155156 // 放入VSE 当中157 SimulationEngine.GlobalInstancePort.Insert(robotBaseEntity);158 }159160 /// <summary>161 /// 产生SimulatedDifferentialDrive 当中已经建立好的虚拟LegoNXTTribot 机器人 162 /// </summary>163 /// <param name="position"></param>164 /// <returns></returns>165 private LegoNXTTribot CreateLegoNxtMotorBase(Vector3 position)166 {167 LegoNXTTribot robotBaseEntity = new LegoNXTTribot(position);168 = CreateNamePlusGuid( "LegoNXTMotorBase" );169170 // 指定VSE 当中的Entity 来启动SimulatedDifferentialDrive 服务171 drive.Contract.CreateService(172 ConstructorPort, " http://localhost/ " + ,173 Microsoft.Robotics.Simulation.Partners.CreateEntityPartner(174 " http://localhost/ " +)175 );176 return robotBaseEntity;177 }178179 /// <summary>180 /// 产生LEGO Next 前方的碰撞感应器181 /// </summary>182 /// <returns></returns> 183 private BumperArrayEntity CreateLegoNxtBumper()184 {185 BoxShape frontBumper = new BoxShape(186 new BoxShapeProperties(187 "front" , 0.001f, //质量188 new Pose( new Vector3(0, 0.063f, -0.09f)), //位置189 new Vector3(0.023f, 0.023f, 0.045f)));190191 // 物理引擎(Physics Engine) 必须要指定这个Entity 启动碰撞通知, 这样虚拟服务才会运作正常192 frontBumper.State.EnableContactNotifications = true ;193194 BumperArrayEntity bumperArray = new BumperArrayEntity(frontBumper);195 = CreateNamePlusGuid( "LegoNXTBumpers" );196197 // 指定Entity 来启动虚拟服务198 bumper.Contract.CreateService(199 ConstructorPort, " http://localhost/ " +,200 Microsoft.Robotics.Simulation.Partners.CreateEntityPartner(201 " http://localhost/ " + ));202 return bumperArray;203 }以上, 因为使用到不少Robotics 内建的simulation , 所以using 要加上:1 using drive = Microsoft.Robotics.Services.Simulation.Drive.Proxy;2 using lrf = serRangeFinder.Proxy;3 using bumper =Microsoft.Robotics.Services.Simulation.Sensors.Bumper.Proxy;4 using simwebcam =Microsoft.Robotics.Services.Simulation.Sensors.SimulatedWebcam.Proxy;当然, 参考的dll 就是SimulatedBumper.Y2006.M05.proxy, SimulatedDifferentialDrive.2006.M06.proxy, SimulatedLRF.Y2006.M05.proxy, SimulatedWebcam.Y2006.M09.proxy, 以上都可以在Robotics Developer Studio 安装目录下面的bin当中找到.但是有一个比较麻烦的dll是Microsoft.Xna.Framework.dll ,它会放在Windows目录下的GAC_32下面,(以我的电脑为例子是C:\WINDOWS\assembly\GAC_32\Microsoft.Xna.Framework\2.0.0.0__6d5c3888ef60e27d )这个microsoft.xna.framework.dll 你可以把它复制出来到robotics studio 安装目录下, 然后再参考比较方便.有了以上那么多行的code, 终于可以加上这行:AddPioneer3DX(new Vector3(1.5f, 0.1f, 0f), -90);然后你就有maze,又有机器人啦(还帮你把角度面对迷宫哩) ...(事实上我也给了产生LegoNXT的code,你可以自己加)简单的做法是把这个Service 丢给VPL 启动, 然后你再加上Dashboard 这个Service, 就可以开始玩机器人走迷宫了.。

第2天Microsoft Robotics Developer Studio中文教程--开始

第2天Microsoft Robotics Developer Studio中文教程--开始

會跳到GenericDifferentialDrive 的設定畫面, 我們選Use a manifest所謂的manifest, 在這裡指的是一整個拖拉庫的服務全部都包起來啦...現在當然還沒能力創建一個manifest, 就直接匯入現有的.然後選這次的活動獎品(目前只有虛擬寶物), LEGO.NXT.Tribot.Simulation.manifest.xmlOkay, 現在你的設定應該是如下圖現在你可以存檔, 開始執行看看會不會有機器車子跑出來了...什麼? 你說你等了好久都沒看到, 又發現跳出Browser 跟你講ERROR ??你該不會是用Vista, 又跟我一樣把Visual Programming Language Express Edtion 裝在那個Program Files 目錄當中吧?? 如果是, 恭喜你, 請把Visual Programming Language Expression Editon 改用系統管理員身分執行吧, 請在開始選單上面對Visual Programming Language Expression Edtion 點選右鍵, 選"以系統管理員身分執行" ,這樣才不會有權限上的問題歐...解決了權限, 再執行一次就應該可以看到如下畫面啦.啊...這樣能幹嘛...因為我們什麼也還沒開始寫啊, 所以現在就只能移動攝影機, 看看畫面這樣而已, 可以用上下左右跟滑鼠操作攝影機移動.那我們趕快來寫點程式來玩它吧^ ^為了能夠操控裏頭的那個虛擬寶物(機器車子), 我們先從service 拖一個Direction Dialog 到Diagram 上, 這個Direction Dialog 會在系統中產生一個有上下左右以及Stop 的五鍵, 好讓我們可以操控虛擬畫面裡面的車子,現在你的Diagram 裡面應該有兩個service 啦.接著要介紹Calculate 這個Basic Activities, 這個Calculate 活動呢, 除了可以做算式運算, 也可以負責拆解訊息, 在VPL 裡面, 訊息可以透過Join 活動組合起來, 也可以透過Calculate 活動拆開, 你可以把訊息想成是某個Class 的物件, 而Calculate 就是負責調用該物件的屬性, Join 就像是把多個屬性合併成為一個新的Class.當然Class 的說明是為了讓那些習慣寫Code 的人來了解的, 事實上, VPL 內部的訊息就是訊息, 可以透過Join 任意組合以及透過Calculate 任意拆解或運算其中的子訊息.寫了一堆, 還是不如直接操作比較容易了解.把Calculate 拉到Diagram 當中之後, 我們把DirectionDialog 的Notification (右下方的紅圈) 拉到Calculate , 表示把DirectionDialog 的通知餵給Calculate, 你會看到Connections 對話框彈出來:這個對話框問我們要把DirectionDialog 的三種通知(ButtonPress : 表示按鍵被按下了, ButtonRelease 表示按鍵被放開了, DialogStateChange 表示對話框的狀態改變了) 哪一種餵給Calculate 呢, 我們選ButtonPress.然後DirectionDialog 就跟Calculate 連上了, 接著我們要選Calculate 中間的輸入, 會有提示下拉, 我們選Name, 表示要從ButtonPress 訊息當中, 拆解出Name 這個訊息(被按下的按鈕名稱) , 這個被按下的按鈕名稱將會被輸出到Calculate 的右端.接著, 我們再從Basic Activites 當中拉一個Switch 活動,這個Switch 活動, 就像是C++ 當中的Switch, 代表根據多個不同的訊息, 我們要採取多個不同的輸出, Switch 左下方有一個"+", 表示你可以新增加一個訊息分岔點, 我們一共要五個(因為有五個按鈕) , 這五個按鈕的名稱分別為"Stop", "Forwards", "Backwards", "Left", "Right" , 新增五個後通通給它填好,然後把剛剛Calculate 的右邊訊息餵給Switch, 現在應該如下圖:接下來要弄VPL 當中最辛苦的資料設定(相較於寫Code 設定資料而言), 請從Basic Activities 當中拖拉7 個Data活動, 型態都是double , 值分別設定為 0, 0.8, -0.8, 0.6,-0.6, 0.6, -0.6 (你可以用複製貼上來加速動作), 然後一一設定連線, 我們把"Stop" 連到0, "Forwards" 連到0.8, "Backwards" 連到-0.8 , "Left" 連到0.6,-0.6 兩個Data, "Right" 則是連到另一組0.6,-0.6 Data , 如下圖:現在我們要開始Join, Merge 這些資料輸出了, Join 剛剛介紹了, 是負責把多個訊息合併成為一個, Merge 也是, 但不同點在於, Join 是把多個訊息組合成為子訊息, 一起輸出, Merge 則是左邊進來右邊出去, 沒有任何改變.請把0, 0.8, -0.8 三個訊息Merge, 把0.6, -0.6 兩組訊息join, 然後分別填上left, right, 如下圖: (請注意, "Left" 那一組的Data 輸出剛好跟"Right" 這一組的Data 輸出, 採取不同的left, right join 方式)讓我們先解決上面的Merge, 把它的輸出餵給一開始的GenericDifferentialDrive , 你會看到對話框彈出來, 我們要把Merge 的輸出對應到車子的油門(SetDrivePower)按下OK, 你會看到另一個對話框, 分別指定左邊輪子的油門跟右邊輪子的油門, 我們通通設為value.這樣我們就完成了前進, 後退, 以及停止啦, 等不及的人可以先按F5 (Run 選單下面的Start) 玩玩看會不會前進後退. 緊接著趕快把"Left", "Right" 設定好, 我們把這兩組Join 好的資料通過Merge , 再輸出給GenericDifferentialDrive , 啊, 一個GenericDifferentialDrive 不願意吃兩個輸入耶, 沒關係, VPL 當中, 物件可以有多個分身, 只要Name 屬性相同, 就表示是相同的物件. (那些沒有Name 屬性的物件, 都是基本物件, 一定不同). 所以你可以複製一個分身, 或者再拖拉一次, 系統會問你是否要新增還是使用原來的物件. (當然是使用原來的).複製好GenericDifferentialDrive 的分身後, 把"Left", "Right" 兩組Join 好的資料透過Merge 再餵給它, 你又看到Connections 的對話框了, 一樣選SetDrivePower, 接著Data Connections 對話框要設定如下:最後, 你的程式就如下圖所示:噹噹, 恭喜你完成可以操控機器車子的程式囉,你可以試玩看看, 但是要常常Stop 歐, 不然一定會像我一樣翻車的我可不知道翻車要怎麼救... 明天我們再來改良吧^ ^ -->。

机器人10大流行编程语言对比,你掌握了哪种?

机器人10大流行编程语言对比,你掌握了哪种?

机器人10大流行编程语言对比,你掌握了哪种?这是一个许多新入行的机器人专家在他们职业生涯中至少会问一次的问题。

不幸的是,这也是一个没有简单答案的问题。

在本文中,我们将会审视在机器人学中最流行的10种编程语言,深入探讨它们各自的优缺点以及使用和弃用它们的原因。

这实际上是个很有道理的问题——毕竟,如果你从不付诸实践,那为什么要花大量的时间和精力去学习一种新的编程语言呢?如果作为一名机器人学新人,你当然会想学习一种确实对你的职业生涯很有用的编程语言。

为什么“这个取决于。

”是个毫无用处的回答不幸的是,如果你去问一屋子的机器人学专家或者在像Stack Overflow、Quora,Trossen,Reddit、 Research Gate这样的论坛上问“什么是机器人学中最好编程语言?”,你永远不会得到一个直接的答案。

电气工程师会从工业机器人技术这个角度给出不同的答案。

计算机视觉程序员给出的答案会跟认知机器人专家给出的不一样。

而且,每个人都会对什么是最好的编程语言有自己的看法。

最终,大多数人都会赞同的答案就是”这个取决于。

“。

对于一个新入行正在试图决定要先学哪种语言的机器人学者来说,这是一个相当无用的答案。

即使这是最现实的回答——因为它的确取决于你想要开发的应用程序和你在使用的系统。

◆ ◆ ◆我究竟应该先学哪种编程语言?我究竟应该先学哪种编程语言?这是一个许多新入行的机器人工程师在他们职业生涯中至少会问一次的问题。

不幸的是,这也是一个没有简单答案的问题。

也许更恰当的问题应该是先从哪种编程语言开始学起?但是,你仍然会得到不同的看法,但是许多机器人专家会同意从关键编程语言开始学。

对于机器人专家来说,最重要的事情是开拓你的”编程思维”,而不是精通一种特定的编程语言。

从很多方面来说,从哪种编程语言开始学习真的无关紧要。

你学习的每种语言提升了你的编程思维,拥有了这种思维,去学习一种新编程语言的时候会容易不少。

在本文中,我们将会审视在机器人学中最流行的10种编程语言,深入探讨它们各自的优缺点以及使用和弃用它们的原因。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Microsoft Robotics Developer Studio 4
学习笔记
案例2:开始玩机器人
1.为了看见车子,我们从“Service”中选择“Simulated Generic Differential Drive”放在“Diagram”上;
①对“Simulated Generic Differential Drive”右击,选择“Set Configuration”;
②跳到“Simulated Generic Differential Drive”的设定界面,选择“Use a manifest”;
③选择“Import Manifest”,导入虚拟机器人;
④选择“LEGO.NXT.Tribot.Simufation.Manifest.xml”
⑤现在保存文件,运行后就能看到“乐高”虚拟机器人了。

2.为了操控虚拟机器人,从“service”中拖一个“Direction Dialog”到“Diagram”中,这个“Direction Dialog”会在系统中产生一个有上下左右及Stop的五个键,让我们可以编程后控制里面的机器人。

3.在“Basic Activities”中找到“Calculate”,把“Calculate”拉到“Diagram”中;
①把“Direction Dialog”的“Notification(右下方的红圈)”拉到“Calculate”,表示把“Direction Dialog”的通知传递给“Calculate”,这时会弹出“Connections”对话框。

②选择“ButtonPress”表示:当鼠标被按下时。

③“DirectionDialog”跟“Calculate”连接后,在“Calculate”中间下拉选择“Name”,表示要从“ButtonPress”信息中,拆解出“Nmae”这个信息(被按下的按钮名称),这个被按下的按钮会被输出到“Calculate”的右端。

4.在“Basic Activites”中拉一个“Switch”元件。

通过“Switch”左下方“+”增加信息分岔点,一共要五个,这五个按钮的名称分别为“Stop”,“Forwards”,“Backwards”,“Left”,“Right”(要求首字母大写,名称有双引号),然后把“Calculate”右边讯息串送给“Switch”。

5.从“Basic Activities”当中拖拉7个“Data”活动,属性都是“double”,属性值分别设定为0,0.8,-0.8,0.6,-0.6,0.6,-0.6,然后逐一设定连线,把“Stop”连到0,“Forwards”连到0.8,“Backwards”连到-0.8,“Left”连到0.6,-0.6两个“Data”,“Right”连到另一组0.6,-0.6两个“Data”。

6.通过“Jion”,“Merge”输出信息。

把0,0.8,-0.8三个参数传递给“Merge”,把0.6,-0.6两个参数传递给“Join”,然后分别填上“left”,“right”。

(向左转弯,右正转左负转,向右转弯,右负转左正转)
7.把“Merge”传递给模拟机器人“Simulated Generic Differential Drive”,在弹出对话框中,把“Merge”输出对应到车子的油门“SetDrivePower”;
按下“OK”后弹出另一个对话框,分别指定左、右轮子的油门,通通设为“value”。

现在已完成前进、后退,以及停止的操控了,可先按F5(Run菜单下的Start)测试。

8.把“Left”,“Right”设定好,把这两组“Join”好的资料串入“Merge”;
复制模拟机器人“Simulated Generic Differential Drive”,把“Left”,“right”两组Join好的资料通过“Merge”串递“Simulated Generic Differential Drive”,在“Connections”对话框中,选择“SetDrivePower”,接着的“Data Connections”对话框设定如下。

到此为止,机器人可以前进、后退、停止、左右转弯,完整程序图如下。

相关文档
最新文档