zoukankan      html  css  js  c++  java
  • 实时控制软件第三次作业-编程作业(更新梯形加速并绘制轨迹)

      之前的博客太长了看起来麻烦所以重新开一个。

    • 之前做的xenomai与gui通信的链接:http://www.cnblogs.com/leafwaltz/p/6169463.html#3579553
    • 源码已上传至GitHub:https://github.com/leafwaltz/TrajectoryBuilder

      添加了一个不发送新消息到达信号的发信函数以进行任务间通信,任务采用定时轮询的方式从消息缓存中读取数据。

      源码如下:

      

     1 void Messenger::PostMessage(Message msg)
     2 {
     3     PostMessageWithoutInforming(msg);
     4 
     5     emit sig_newMessageIn(msg.type);
     6 }
     7 
     8 void Messenger::PostMessageWithoutInforming(Message msg)
     9 {
    10     map<int,queue<Message>>::iterator it = m_messageTemp.find(msg.type);
    11 
    12     if(it==m_messageTemp.end())
    13     {
    14         queue<Message> newMessageQueue;
    15         newMessageQueue.push(msg);
    16         pthread_mutex_t newMutex;
    17         pthread_mutex_init(&newMutex,NULL);
    18         m_messageTemp.insert(pair<int,queue<Message>>{msg.type,newMessageQueue});
    19         m_messageTempMutex.insert(pair<int,pthread_mutex_t>{msg.type,newMutex});
    20     }
    21     else
    22     {
    23         pthread_mutex_lock(&m_messageTempMutex[msg.type]);
    24         it->second.push(msg);
    25         pthread_mutex_unlock(&m_messageTempMutex[msg.type]);
    26     }
    27 }
    • 目前添加了梯形调速的测试程序,并在gui上绘制轨迹,运行效果如下,gif太大了传不上来= =,晚一点压缩了传上来:

    • 画布尺寸目前设定为500x500大小,所以设置了比较小的参数,在命令处理的部分还没有加缓存所以目前只支持单次命令发送,之后会添加一个缓存用于存储命令
    • 目前的调速频率设置为0.1s,每0.1s在画布上绘制一次点的位置
    • 任务间不再使用全局变量进行通信,使用messenger的PostMessageWithoutInforming和ReceiveMessage来进行通信
    • 封装了xenomai任务使其更符合c++的使用习惯:
     1 #ifndef TASKMANAGER_H
     2 #define TASKMANAGER_H
     3 
     4 #include "userheaders.h"
     5 
     6 class Task
     7 {
     8 
     9 public:
    10 
    11     typedef void(*RT_TASK_FUNC)(void*);
    12 
    13     Task(const char* taskname, int prior, int stacksize = 0, int mode = 0);
    14 
    15     ~Task();
    16 
    17     bool StartTask();
    18 
    19     void DeleteTask();
    20 
    21     int GetPriority() const;
    22 
    23     QString GetTaskName() const;
    24 
    25     Task& operator +=(const RT_TASK_FUNC rttask_func);
    26 
    27 private:
    28 
    29     RT_TASK_FUNC m_rttask_func;
    30 
    31     RT_TASK m_rttask;
    32 
    33     QString m_taskname;
    34 
    35     int m_stacksize;
    36 
    37     int m_priority;
    38 
    39     int m_mode;
    40 
    41 };
    42 
    43 
    44 #endif // TASKMANAGER_H

      可以使用重载的+=运算符来进行任务的注册:

    1 task_trajectory_generator += task_trajectory_generator_proc;
    2 task_command_sender += task_command_sender_proc;
    3 task_trajectory_generator.StartTask();
    4 task_command_sender.StartTask();
    • 下一步的计划:
    1. 添加一个命令缓存器;
    2. 试着将调速修改成S形调速;
    3. 检查内存泄漏问题,进行细节规划(改成shared_ptr跟xenomai和qt对接十分困难,只能自己手动管理内存了= =);
    4. 在命令输入部分加入查错机制,使用MessageBox进行输入错误的提示;
    5. (如果有需要)在界面增加更多的用户输入接口。
  • 相关阅读:
    FreeNAS的安装使用记录
    slackware中配置命令行下的分辨率
    创建类的理由
    软件开发人员的入门级书单
    Pow(x, n)
    Group Anagrams
    Rotate Image
    Permutations
    Multiply Strings
    Combination Sum II
  • 原文地址:https://www.cnblogs.com/leafwaltz/p/6182824.html
Copyright © 2011-2022 走看看