| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2935 人关注过本帖
标题:求助大神一个关于机器人编程的问题。Microsoft robotics developer studio ...
取消只看楼主 加入收藏
hhjy121
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2016-5-21
结帖率:0
收藏
已结贴  问题点数:20 回复次数:2 
求助大神一个关于机器人编程的问题。Microsoft robotics developer studio 和 C#
我在学习机器人编程的时候遇到一个难题了。

情况是这样的,Microsoft 有个软件叫做 Microsoft robotics developer studio (MRDs), 然后在这个软件里面有一些例子代码(sample code)可以让我们学习,他们的官方也提供这些教程讲解这些东西。然后我花费了很多时间之后,终于可以让模拟环境(simulation environment)运行起来。这样就可以不用买真实的机器也可以自学和改进编程。

原本的code是只能控制前进,后退,左转,右转,还有停下。我在原有的code那边又加了一个按键,就是path(路径)。因为我想让机器人走一个固定的路径,而不是让我们去控制机器人前后左右的移动。

那么在产生弄这个的时候,我用了2种办法。
第一种办法就是通过设置时间,然后在这个固定的时间之类,机器人完成一定的路径。这个办法的缺点就是没有办法精确机器人走多远和旋转的角度(可能有计算的方法,但是暂时我不知道,而且感觉处理器的负担也很大,因为要一直计算着时间。)

第二种办法,就是我现在正在尝试的,那就是设置固定的距离,速度, 还有旋转的角度。
这个办法的好处就是精确,但问题是,我只能够执行其中一个命令。当我把这走动的距离跟旋转的角度放到loop里面的时候,他只会执行最后一个命令,第一个命令会被直接覆盖掉。

我的问题就是,如果能够解决这个问题?只需要按一下按键,那么机器人就会走你编辑的路径。
在此先谢过大家的帮忙了。谢谢。
以下是我代码(只有最后一部分是我加进去的,其余的是原本 Microsoft 的例子代码):
//-----------------------------------------------------------------------
//  This file is part of Microsoft Robotics Developer Studio Code Samples.
//
//  Copyright (C) Microsoft Corporation.  All rights reserved.
//
//  $File: RoboticsTutorial4.cs $ $Revision: 22 $
//-----------------------------------------------------------------------
using Microsoft.Ccr.Core;
using Microsoft.Ccr.Adapters.WinForms;
using Microsoft.Dss.Core;
using Microsoft.Dss.Core.Attributes;
using Microsoft.Dss.ServiceModel.Dssp;
using Microsoft.Dss.ServiceModel.DsspServiceBase;
using System;
using System.Collections.Generic;
using System.Security.Permissions;
using xml = System.Xml;
using drive = Microsoft.Robotics.Services.Drive.Proxy;
using W3C.Soap;
using Microsoft.Robotics.Services.RoboticsTutorial4.Properties;
using Microsoft.Robotics.Services.Drive.Proxy;
using


namespace Microsoft.Robotics.Services.RoboticsTutorial4
{
    [DisplayName("(User) Robotics Tutorial 4 (C#): Drive-By-Wire")]
    [Description("This tutorial demonstrates how to create a service that partners with abstract, base definitions of hardware services.")]
    [DssServiceDescription("http://msdn.)]
    [Contract(Contract.Identifier)]
    public class RoboticsTutorial4 : DsspServiceBase
    {
        [ServiceState]
        private RoboticsTutorial4State _state = new RoboticsTutorial4State();

        [ServicePort("/RoboticsTutorial4", AllowMultipleInstances=false)]
        private RoboticsTutorial4Operations _mainPort = new RoboticsTutorial4Operations();

        [Partner("Drive", Contract = drive.Contract.Identifier, CreationPolicy = PartnerCreationPolicy.UseExisting)]
        private drive.DriveOperations _drivePort = new drive.DriveOperations();
        private drive.DriveOperations _driveNotify = new drive.DriveOperations();

        public RoboticsTutorial4(DsspServiceCreationPort creationPort) :
                base(creationPort)
        {
        }

        #region CODECLIP 02-1
        protected override void Start()
        {
            base.Start();

            WinFormsServicePort.Post(new RunForm(StartForm));

            #region CODECLIP 01-5
            _drivePort.Subscribe(_driveNotify);
            Activate(Arbiter.Receive<drive.Update>(true, _driveNotify, NotifyDriveUpdate));
            #endregion
        }
        #endregion

        #region CODECLIP 02-2
        private System.Windows.Forms.Form StartForm()
        {
            RoboticsTutorial4Form form = new RoboticsTutorial4Form(_mainPort);

            Invoke(delegate()
                {
                    PartnerType partner = FindPartner("Drive");
                    Uri uri = new Uri(partner.Service);
                    form.Text = string.Format(
                        Resources.Culture,
                        Resources.Title,
                        uri.AbsolutePath
                    );
                }
            );

            return form;
        }
        #endregion

        #region CODECLIP 02-3
        private void Invoke(System.Windows.Forms.MethodInvoker mi)
        {
            WinFormsServicePort.Post(new FormInvoke(mi));
        }
        #endregion


        /// <summary>
        /// Replace Handler
        /// </summary>
        [ServiceHandler(ServiceHandlerBehavior.Exclusive)]
        public virtual IEnumerator<ITask> ReplaceHandler(Replace replace)
        {
            _state = replace.Body;
            replace.ResponsePort.Post(DefaultReplaceResponseType.Instance);
            yield break;
        }

        [ServiceHandler(ServiceHandlerBehavior.Concurrent)]
        //stop
        public virtual IEnumerator<ITask> StopHandler(Stop stop)
        {
            drive.SetDrivePowerRequest request = new drive.SetDrivePowerRequest();
            request.LeftWheelPower = 0;
            request.RightWheelPower = 0;

            yield return Arbiter.Choice(
                _drivePort.SetDrivePower(request),
                delegate(DefaultUpdateResponseType response) { },
                delegate(Fault fault)
                {
                    LogError(null, "Unable to stop", fault);
                }
            );
        }

        //forward
        #region CODECLIP 01-3
        [ServiceHandler(ServiceHandlerBehavior.Concurrent)]
        //forward
        public virtual IEnumerator<ITask> ForwardHandler(Forward forward)
        {
            if (!_state.MotorEnabled)
            {
                yield return EnableMotor();
            }
            // movement speed
            // This sample sets the power to 75%.
            // Depending on your robotic hardware,
            // you may wish to change these values.
            drive.SetDrivePowerRequest request = new drive.SetDrivePowerRequest();
            request.LeftWheelPower = 0.5;
            request.RightWheelPower = 0.5;

            yield return Arbiter.Choice(
                _drivePort.SetDrivePower(request),
                delegate(DefaultUpdateResponseType response) { },
                delegate(Fault fault)
                {
                    LogError(null, "Unable to drive forwards", fault);
                }
            );
        }
        #endregion

        [ServiceHandler(ServiceHandlerBehavior.Concurrent)]
        // backup speed
        public virtual IEnumerator<ITask> BackwardHandler(Backward backward)
        {
            if (!_state.MotorEnabled)
            {
                yield return EnableMotor();
            }

            drive.SetDrivePowerRequest request = new drive.SetDrivePowerRequest();         
            request.LeftWheelPower = -0.6;
            request.RightWheelPower = -0.6;

            yield return Arbiter.Choice(
                _drivePort.SetDrivePower(request),
                delegate(DefaultUpdateResponseType response) { },
                delegate(Fault fault)
                {
                    LogError(null, "Unable to drive backwards", fault);
                }
            );
        }

        [ServiceHandler(ServiceHandlerBehavior.Concurrent)]
        // left turn speed
        public virtual IEnumerator<ITask> TurnLeftHandler(TurnLeft turnLeft)
        {
            if (!_state.MotorEnabled)
            {
                yield return EnableMotor();
            }

            drive.SetDrivePowerRequest request = new drive.SetDrivePowerRequest();
            request.LeftWheelPower = -0.5;
            request.RightWheelPower = 0.5;

            yield return Arbiter.Choice(
                _drivePort.SetDrivePower(request),
                delegate(DefaultUpdateResponseType response) { },
                delegate(Fault fault)
                {
                    LogError(null, "Unable to turn left", fault);
                }
            );
        }

        [ServiceHandler(ServiceHandlerBehavior.Concurrent)]
        // right turn speed
        public virtual IEnumerator<ITask> TurnRightHandler(TurnRight forward)
        {
            if (!_state.MotorEnabled)
            {
                yield return EnableMotor();
            }

            drive.SetDrivePowerRequest request = new drive.SetDrivePowerRequest();
            request.LeftWheelPower = 0.5;
            request.RightWheelPower = -0.5;

            yield return Arbiter.Choice(
                _drivePort.SetDrivePower(request),
                delegate(DefaultUpdateResponseType response) { },
                delegate(Fault fault)
                {
                    LogError(null, "Unable to turn right", fault);
                }
            );
        }

        #region CODECLIP 01-4
        private Choice EnableMotor()
        {
            drive.EnableDriveRequest request = new drive.EnableDriveRequest();
            request.Enable = true;

            return Arbiter.Choice(
                _drivePort.EnableDrive(request),
                delegate(DefaultUpdateResponseType response) { },
                delegate(Fault fault)
                {
                    LogError(null, "Unable to enable motor", fault);
                }
            );
        }
        #endregion

        #region CODECLIP 01-6
        private void NotifyDriveUpdate(drive.Update update)
        {
            RoboticsTutorial4State state = new RoboticsTutorial4State();
            state.MotorEnabled = update.Body.IsEnabled;

            _mainPort.Post(new Replace(state));
        }
        #endregion


        // Here is where I had change the code.
        #region Test Code (Creating Path)
        [ServiceHandler(ServiceHandlerBehavior.Concurrent)]
        public virtual IEnumerator<ITask> PathHandler(StartPath path)
        {
            if (!_state.MotorEnabled)
            {
                yield return EnableMotor();
            }

            for(int i=1; i<3; i++)
            {
                    if(i == 1)
                    {
                        drive.DriveDistanceRequest distance = new drive.DriveDistanceRequest();
                        distance.Power = 1;
                        distance.Distance = 1;

                        yield return Arbiter.Choice(
                            _drivePort.DriveDistance(distance),
                            delegate(DefaultUpdateResponseType response) { },
                            delegate(Fault fault)
                            {
                                LogError(null, "Unable to turn left", fault);
                            }
                        );

                    }
                    else if(i == 2)
                    {
                        drive.RotateDegreesRequest rotate = new drive.RotateDegreesRequest();
                        rotate.Power = 1;
                        rotate.Degrees = 90;

                        yield return Arbiter.Choice(
                            _drivePort.RotateDegrees(rotate),
                            delegate(DefaultUpdateResponseType response) { },
                            delegate(Fault fault)
                            {
                                LogError(null, "Unable to turn left", fault);
                            }
                        );
                    }
               
            }

        }
        #endregion
    }
}
搜索更多相关主题的帖子: Microsoft developer 机器人 软件 
2016-05-21 07:41
hhjy121
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2016-5-21
收藏
得分:0 
以下是引用yhlvht在2016-5-21 10:36:25的发言:

首先挺佩服楼主的专研精神
这个我并没有研究过,不过从代码上看,因为用了委托来执行,线程不会阻塞,所以在循环中,if(i == 1)的代码执行完以后,马上就会循环到else if(i == 2),所以第一个指令就中断了
需要i == 1的代码执行后,有一段时间让机器人行动,再执行i == 2才行
所以你需要研究一下线程方面的东西,比如线程休眠、等待、唤醒,或是线程同步
最好是看看有没有类似完成事件一样的东西,就是当机器人执行完某一个指令的时候,会发出通知,告知已经执行完成某一指令
收到通知以后再执行下一指令的代码,在收到通知以前,线程就一直等待



嗯,我之前的想法也是这样的。但是当我实际操作起来去写这个code的时候却不知道要如何下手。(我的C#语言并不好)

我原本的想法是 弄一个function,然后那个function 是专门用来 核对如果那个命令执行完成了或者没有。如果完成了,那么return true, 之后执行第二个命令。否者 return false这样。
但是我不知道要如何的去修改。所以想问一下论坛里有哪位大神的C#比较精通的。


2016-05-22 02:34
hhjy121
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2016-5-21
收藏
得分:0 
以下是引用cpxuvs在2016-5-22 13:38:03的发言:

还是先学好基础再弄这些吧。

我是小白呵呵


我其实懂的也不懂。就是边试边学。只要懂基本的C++,再去大概看一下C#。我就是这样开始的,虽然结果不是很好,但好在还是看的懂一些。
2016-05-23 11:57
快速回复:求助大神一个关于机器人编程的问题。Microsoft robotics developer st ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.056335 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved