766游戏网官网其三周作业

一、不同实时操作系统的特性和相比

1、Vxworks

Vxworks在实时操作系统行业内处于超过地位,拥有许多的用户。它辅助32位、64位以及多核处理器,帮忙ARM、AMD、PowerPC等系统。首要接纳于国防、航空航天、汽车、医疗和工业领域。它兼具可以的开支环境和软件补助,可是昂贵的价钱让开发者望而却步。

2、QNX

QNX是一个分布式、嵌入式、可规模扩充、服从POSIX规范的类Unix微内核硬实时操作系统。首要用于商用,目的市场紧倘诺面向嵌入式系统。
其根本独立自处于一个被保障的地点空间,驱动程序、网络协议和应用程序处于程序空间中。内核仅提供4种服务:进程调度、进程间通信、底层网络通信和间断处理。所有其他OS服务,都实现为合作的用户进程,在单独的地方空间运行。由此QNX内核分外精美(QNX4.x大体为12Kb),运行速度极快;操作系统模块与根本互相独立,具有很高的可靠性。而且与UNIX具有莫大相似性,使得为数众多的安宁成熟的UNIX、LINUX应用可以直接移植到QNX这一个更加安宁连忙的实时嵌入式平台上。

3、Xenomai

Xenomai是一个在Linux平台上确立起的通用实时框架的自由软件项目。
早期Xenomai是一种在动用双内核机制时对不可能用来强实时利用的Linux内核的恢弘,其事先级高于Linux
内核。后来逐级提升成一个老谋深算的实时Linux架构。
Xenomai
实时内核为付出强实时拔取提供了增长的效用,首要包括实时线程调度与治本、用户空间实时任务扶助、线程同步服务、时钟服务、中断服务、动态内存申请和实时对象注册服务等。重要用于工业自动化行业。

4、Intime

INtime是与 Windows 操作系统共享硬件平台的实时操作系统。
766游戏网官网,Windows内核驱动程序管理用于运行基本和实时应用程序的内存,并且管理这五个序列里面的通讯接口。INtime
内核为实时虚拟机提供操作系统服务,包括一个依据优先级的超越式计划程序,该程序执行基于优先级的刹车处理。内核计划程序已经开展优化,以拿到最佳的间歇性能。

4、Sylixos

SylixOS 是一款由中华人独立设计开发的大型嵌入式硬实时操作系统,帮助 SMP
多核,具有充裕的文件系统、网络体系以及无数配备驱动援助,并提供周全的合一开发条件。经过长年累月的频频开发与革新,已经变为一个保险稳定,效用周密,易于开发调试的嵌入式实时系统开发平台。SylixOS的降生可以解脱国内有的主体设备对海外嵌入式操作系统的依靠,为国内的嵌入式消息技术行业提供一个簇新的选用。现已采取于航空航天与国防导弹等世界。

5、ucos

UCOS
是一个能够依照ROM运行的、可减掉的、抢占式、实时多任务内核,具有莫大可移植性的嵌入式实时操作系统。特别契合于统计机和控制器,适合过多经贸操作系统。有着完整的网络序列和文件系统,并且开放源代码。效率支撑TCP/IP、USB、CAN总线、Modbus。具有一个无敌的文件系统和图形用户界面。UCOS采纳可剥夺型实时多任务内核,其任务调度是完全遵照任务优先级的抢占式调度,具有可靠及连忙等特性。在修建工业控制、医疗设备、航天系统等世界有周边的施用。

二、团队项目

成就一个团伙项目,重要效率是落实一个两轴机械手的位移控制仿真,首要意义包括:

  • 用户接口任务:负责接收来自用户的伸手,并发送运动指令给轨道插补任务。
  • 轨道插补任务:接收运动指令,实时总结各轴的职位和进度设定值。
  • 大体引擎接口:基于ODE开源物理引擎,创立一个两轴机械手及条件的情理模型,用轨迹插补任务输出的各轴地点和进度设定值控制模型的移动,并把实时意况反映给轨道插补任务。
  • 图形化用户接口:可依照qt把上述功效集成到一个GUI界面。

自我对轨道插补任务和图形化用户接口比较感兴趣。我往日插手过一些嵌入式项目,有较强的编辑代码的力量。在《数控系统》的就学过程中,就对插补很感兴趣。其余,我也希望能够接触部分图形化的编程,学习一下这地点的知识。

三、编程实现稳定运动轨迹生成器

在task_trajectory_generator任务中扩充代码来处理来自task_command_sender的永恒运动命令new_cmd,遵照该命令中提交的职务、速度、加速度、减速度,实现一个梯形加减速(原理见数控技术教材)的移位轨迹生成器,当达到目的地方时,把new_cmd.Done设为true,主程序检测到new_cmd.Done为true时将扫尾运行。
编程要求:

  • 轨道生成器的代码结构能充裕显示出基于状态机的编程方法。
  • 把第一个可以运作的本子发布到温馨的github账号上,并持续优化和交由。
  • 创办一个TODO.md文档写下自己的编程思路和下一步要做的劳作。

为了收缩运行时刻和改革输出的职能,我改变了new_cmd命令中的Position值,注释掉了Task
提姆e的printf部分,并将task_trajectory_generator的职责周期改为0.1s。
V1.0代码已公告到GitHub上

https://github.com/liqi120150/simple_motion.git

如下:

#include <stdio.h>
#include <math.h>
#include <signal.h>
#include <unistd.h>
#include <sys/mman.h>

#include <native/task.h>
#include <native/timer.h>

// Data Type

typedef struct
{
    bool Request;
    bool Response;
    bool Done;
    double Position;
    double Velocity;
    double Acceleration;
    double Deceleration;
    double Jerk;
} tPosCmd;

typedef struct
{
    double Position;
    double Velocity;
} tAxisSetpoint;

//Global variables

RT_TASK task_trajectory_generator;
RT_TASK task_command_sender;

tPosCmd new_cmd;
tAxisSetpoint axis1_setpoint;

int cycle_count = 0;

/*****************************************************
 * status machine
 * 
*****************************************************/
typedef enum
{
    Idel = 0,
    Accelerate,
    Decelerate,
    UniformVelocity 
}trajectoryStatusDef;

#define Position_DeadSize   10
#define Velocity_DeadSize   10
void task_trajectory_generator_proc(void *arg)
{
    RTIME now, previous;
    trajectoryStatusDef Status = Idel;

    /*
     * Arguments: &task (NULL=self),
     *            start time,
     *            period (here: 0.1 s)
     */
    rt_task_set_periodic(NULL, TM_NOW, 100000000);
    previous = rt_timer_read();

    axis1_setpoint.Position = 0;
    axis1_setpoint.Velocity = 0;

    int temp;

    float delta_T;
    while (1) {
        rt_task_wait_period(NULL);
        now = rt_timer_read();

        /*
         * NOTE: printf may have unexpected impact on the timing of
         *       your program. It is used here in the critical loop
         *       only for demonstration purposes.
         */
        /*
        printf("Task A Time since last turn: %ld.%06ld ms\n",
               (long)(now - previous) / 1000000,
               (long)(now - previous) % 1000000);
        */


        //  Add your code
        delta_T = ((double)(now - previous) / 1000000000);
        previous = now;

        if(new_cmd.Request)
        {
            printf("Position:%10.3f,Velocity:%10.3f at time:%10.3f s.\r\n", 
                axis1_setpoint.Position,
                axis1_setpoint.Velocity,
                (double)now / 1000000000);
            if(fabs(new_cmd.Position - axis1_setpoint.Position) > Position_DeadSize)
            {
                if(fabs(new_cmd.Velocity - axis1_setpoint.Velocity) > Velocity_DeadSize)
                {
                    if(fabs((axis1_setpoint.Velocity * axis1_setpoint.Velocity) / (2*new_cmd.Deceleration)) >= fabs(new_cmd.Position - axis1_setpoint.Position))
                    {
                        if(axis1_setpoint.Velocity > 0)
                            Status = Decelerate;
                        else
                            Status = Accelerate;
                    }
                    else if(new_cmd.Velocity > axis1_setpoint.Velocity)
                        Status = Accelerate;
                    else
                        Status = Decelerate;
                }
                else
                {
                    if(fabs((axis1_setpoint.Velocity * axis1_setpoint.Velocity) / (2*new_cmd.Deceleration)) >= fabs(new_cmd.Position - axis1_setpoint.Position))
                    {
                        if(axis1_setpoint.Velocity > 0)
                            Status = Decelerate;
                        else
                            Status = Accelerate;
                    }
                    else
                        Status = UniformVelocity;
                }
            }
            else
            {
                Status = Idel;
                new_cmd.Response = true;
                new_cmd.Done = true;
            }
            switch(Status)
            {
                case Accelerate:
                    //s = s0 + v0*delta_T + 0.5*acce*(delta_T^2)
                    axis1_setpoint.Position += axis1_setpoint.Velocity*delta_T + 0.5*new_cmd.Acceleration * (delta_T * delta_T);
                    //v = v0 + acce*delta_T
                    axis1_setpoint.Velocity += new_cmd.Acceleration*delta_T;
                    break;
                case Decelerate:
                    //s = s0 + v0*delta_T - 0.5*Deceleration*(delta_T^2)
                    axis1_setpoint.Position += axis1_setpoint.Velocity*delta_T - 0.5*new_cmd.Deceleration * (delta_T * delta_T);
                    //v = v0 - Deceleration*delta_T
                    axis1_setpoint.Velocity -= new_cmd.Deceleration*delta_T;    
                    break;
                case UniformVelocity:
                    //s = s0 + v0*delta_T;
                    axis1_setpoint.Position += axis1_setpoint.Velocity*delta_T;
                    break;
                case Idel:
                    break;
                default:
                    break;
            }
        }


    }
}

void task_command_sender_proc(void *arg)
{
    RTIME now, previous;

    /*
     * Arguments: &task (NULL=self),
     *            start time,
     *            period (here: 2 s)
     */
    rt_task_set_periodic(NULL, TM_NOW, 2000000000);
    previous = rt_timer_read();

        new_cmd.Request = false;
        new_cmd.Response = false;
        new_cmd.Done = false;
        new_cmd.Position = 0;
        new_cmd.Velocity = 0;
        new_cmd.Acceleration = 0;
        new_cmd.Deceleration = 0;
        new_cmd.Jerk = 0;

    while (1) {
        rt_task_wait_period(NULL);
        now = rt_timer_read();

        /*
         * NOTE: printf may have unexpected impact on the timing of
         *       your program. It is used here in the critical loop
         *       only for demonstration purposes.
         */
         /*
        printf("Task B Time since last turn: %ld.%06ld ms\n",
               (long)(now - previous) / 1000000,
               (long)(now - previous) % 1000000);
        */
               previous = now;
                cycle_count = cycle_count + 1;
                printf("cycle_count:%d\n",cycle_count);

                if(cycle_count == 5)
                {
                    new_cmd.Request = true;
                    new_cmd.Response = false;
                    new_cmd.Done = false;
                    new_cmd.Position = 20000;
                    new_cmd.Velocity = 1000;
                    new_cmd.Acceleration = 50;
                    new_cmd.Deceleration = 50;
                    new_cmd.Jerk = 0;

                }

    }
}

void catch_signal(int sig)
{

}


int main(int argc, char* argv[])
{
    signal(SIGTERM, catch_signal);
    signal(SIGINT, catch_signal);

    /* Avoids memory swapping for this program */
    mlockall(MCL_CURRENT|MCL_FUTURE);

        printf("A simple motion control demo\n");
    /*
     * Arguments: &task,
     *            name,
     *            stack size (0=default),
     *            priority,
     *            mode (FPU, start suspended, ...)
     */
    rt_task_create(&task_trajectory_generator, "rttask_trajectory_generator", 0, 99, 0);
    rt_task_create(&task_command_sender, "rttask_command_sender", 0, 98, 0);

    /*
     * Arguments: &task,
     *            task function,
     *            function argument
     */
    rt_task_start(&task_trajectory_generator, &task_trajectory_generator_proc, NULL);
    rt_task_start(&task_command_sender, &task_command_sender_proc, NULL);

        while(!new_cmd.Done);
        printf("End! \n");
    rt_task_delete(&task_trajectory_generator);
    rt_task_delete(&task_command_sender);
    return 0;
}

代码运行效果:
766游戏网官网 1

大庭广众,如今的代码应用全局变量举办任务间的通信,且四回只可以发送一个一定命令。计划下一步使用Queue来进展通信,实现命令的缓冲和活动轨迹的平整工作。

发表评论

电子邮件地址不会被公开。 必填项已用*标注