• 工作日志(二)


    个人编程作业——轨迹插补完善

    轨迹插补中有两个函数模块——指令发送和轨迹生成。指令发送函数发送的数据有:

    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;

    以上是他们的初始状态。


    算法原理:

    1. 当循环次数达到5次时,将Request置1,即开始发送数据;
    2. 轨迹生成函数得到Request为真的信息后,先将Response 置1,然后开始生成轨迹;
    3. 要求生成梯形轨迹插补,其特点是Acceleration =Deceleration ,方向相反。
    4. 已经从指令中得到目标位置Position,匀速时的速度Velocity,要求的加速度Acceleration及减速度Deceleration,那么轨迹插补时,以距离将插补分为三段:

    令:
    double p=new_cmd.Position;
    double v=new_cmd.Velocity;
    double a=new_cmd.Acceleration;
    double d=new_cmd.Deceleration;


    if(axis1_setpoint.Position < vv/(2a)),匀加速段;
    else if(axis1_setpoint.Position < p - v*v/d),匀速段;
    else if(axis1_setpoint.Position < p),匀减速段。

    具体插补过程如下:

    • 设置插补周期T;
    • 在一个插补周期中认为是匀速运动,给出速度和目标位置;
    • 当插补周期足够小时,插补轨迹无线接近于梯形轨迹。

    代码实现:

    double T=10;// 插补周期 
    void task_trajectory_generator_proc(void *arg) 
    { 
    	RTIME now, previous; 
    
     
    	/* 
    	 * Arguments: &task (NULL=self), 
    	 *            start time, 
    	 *            period (here: 1 s) 
    	 */ 
    	rt_task_set_periodic(NULL, TM_NOW, 1000000000); 
    	previous = rt_timer_read(); 
    
     
    	axis1_setpoint.Position = 0; 
    	axis1_setpoint.Velocity = 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 A Time since last turn: %ld.%06ld ms
    ", 
    		//        (long)(now - previous) / 1000000, 
    		//        (long)(now - previous) % 1000000); 
    		       previous = now; 
    
     
    		//  Add your code 
    		if(new_cmd.Request) 
    		{ 
    			new_cmd.Response = true; 
    			double p=new_cmd.Position; 
    			double v=new_cmd.Velocity; 
    		 	double a=new_cmd.Acceleration; 
    			double d=new_cmd.Deceleration; 
    			// printf("p,v,a,d: %f.%f.%f.%f 
    ", 
    			//   p, 
    			//   v, 
    			//   a, 
    			//   d); 
    
    			//accelerate   
    			if(axis1_setpoint.Position < v*v/(2*a)) 
    			{ 
    				axis1_setpoint.Velocity += a*T; 
    				axis1_setpoint.Position += axis1_setpoint.Velocity*T; 
    				printf("Position1:%f
    ",axis1_setpoint.Position); 
    			} 
    
    			//constant motion 
    			 else if(axis1_setpoint.Position < p - v*v/d) 
    			{ 
    				axis1_setpoint.Velocity = v; 
    				axis1_setpoint.Position += v*T; 
    				printf("Position2:%f
    ",axis1_setpoint.Position); 
    			} 
    
    		  	//Decelerate 
    			else if(axis1_setpoint.Position < p) 
    			{ 
    				axis1_setpoint.Position += axis1_setpoint.Velocity*T; 
    				axis1_setpoint.Velocity -= d*T; 
    				printf("Position3:%f
    ",axis1_setpoint.Position); 
    			} 
    
    			new_cmd.Done = true; 
    		} 
    	} 
    }
    

    当到达目标位置时,将Done置1,程序结束。

    运行结果图:

  • 相关阅读:
    参数innodb_force_recovery影响了整个InnoDB存储引擎的恢复状况
    innodb_fast_shutdown的内幕
    MySQL关闭过程详解和安全关闭MySQL的方法
    MySQL优化之Explain命令解读,optimizer_trace
    使用Amanda ZRM备份远程MySQL数据库
    类Unix上5个最佳开源备份工具 Bacula/Amanda/Backupninja/Backuppc/UrBackup
    获取 MySQL 崩溃时的 core file
    使用mysqldump备份时为什么要加上 -q 参数(5.7默认为on)
    关联与下钻:快速定位MySQL性能瓶颈的制胜手段
    MySQL安全策略
  • 原文地址:https://www.cnblogs.com/lihanyan/p/6268438.html
Copyright © 2020-2023  润新知