实时控制软件第三次作业-编程作业(更新梯形加速并绘制轨迹)

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

  • 之前做的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. (如果有需要)在界面增加更多的用户输入接口。
原文地址:https://www.cnblogs.com/leafwaltz/p/6182824.html