把我捐了?好笑

三十之年得一女,自然如心肝宝贝一般,不过我对于如何照顾婴儿实在是
一窍不通,我向老婆长叹,然后聪耳不闻老婆的抱怨和怒气,做起了“甩手爸爸”。

一转眼,女儿四岁了。这期间,老婆抱着女儿回娘家四次。最过分的一次
是女儿大便,我正在上网,老婆在厨房忙做饭,河东狮吼般让我替女儿擦屁股,我就
地取材拿了一张打印纸,结果被老婆“上纲上线”,说我根本不配当爸爸,抱着女儿就
回了娘家。

过了几日,我估计老婆已经消气,于是登门道歉,把娘俩结了回来。当然
日子还是照样过,老婆照样一天到晚怒气冲天,无非老生常谈,批判我不做家务不带
孩子。

女儿四岁生日,很隆重地庆祝了一下,爷爷奶奶外公外婆舅舅舅妈呼啦啦
坐了一桌。
吹灭了生日蜡烛,小舅妈笑着问:“小寿星长大了当什么呀?”
女儿小脸一扬,脆生生地答:“当爸爸!”
大家都有些发愣,爷爷说:“你是女孩,长大了只能当妈妈呀。”
女儿说:“我才不要当妈妈,当妈妈一天到晚做事。我要当爸爸,当爸爸不做
事。”
好家伙,一桌人的目光齐刷刷地在我身上定格,老婆更在桌下狠命地拧了我一
把,我急忙招呼:吃菜,吃菜……

后来老婆就常把女儿的这句话挂在嘴边,说,你看看,你看看,你给孩子
留了什么印象,连这么小的孩子都知道当妈妈辛苦,你却一点都不知道体贴我……老婆
说着就要擦泪,我只好赔笑脸。

那日正在家中枯坐,社区里的一位好婆敲门进来,说是为某灾区募捐来
了,问,你女儿可有不穿的衣服?不妨捐出来。
女儿在旁边看好婆和老婆谈得热烈,不解地问:“妈妈,什么东西可以捐呀?”
老婆很实际地回答:“就是家里没有用的东西。”

没有用的东西?女儿环顾着室内,然后一双大眼睛看着我眨呀眨:“妈妈,把爸
爸捐了吧。”
我惊跳起来——什么?
女儿躲在老婆身后不服气地说:“爸爸不烧饭不洗衣服也不陪我玩,爸爸就是没
有用的东西!”
那一刻,我第一次觉得自己34岁的人生真叫失败啊。

后来,我就开始洗衣服做饭帮老婆分担家务了,老婆慢慢地温柔起来,女
儿也开始粘我了。只是,只要我一动什么坏念头,晚上就会做梦,梦见老婆和女儿异
口同声地说:不如把他捐了吧……
<think>我们之前已经分析了速度环控制不平滑的可能原因,并给出了优化建议。现在用户反馈即使将P参数调为0.5,效果仍然不理想。这说明问题可能不仅仅是比例增益过大,还有其他因素。 结合引用[1]中关于雅可比矩阵零空间的描述(机械臂控制中保持末端不动),我们可以联想到电机控制中的类似问题:即使电机在运动,但速度环的波动导致实际输出不平滑。此外,引用[3]中提到的PD控制抗干扰性也与此相关。 针对用户的具体问题,我们深入分析: 1. **PID参数整定问题**:虽然P参数已经降低到0.5,但积分项和微分项可能不合适。特别是积分项,过大的积分增益会导致积分饱和,引起系统振荡。同时,微分项可能放大了编码器的噪声。 2. **编码器反馈问题**:编码器计数在中断中更新,但可能存在噪声或丢失脉冲的情况。在低速时,编码器的分辨率不足也会导致速度计算不准确。 3. **控制周期问题**:用户使用的是20ms的控制周期(由定时器中断决定),这个周期对于高速电机可能过长,导致控制不及时。 4. **死区补偿问题**:用户设置了死区补偿(MIN_DUTY=15),但死区补偿的引入可能导致在目标速度附近出现跳跃现象。 5. **电机非线性特性**:电机的摩擦力矩和负载变化可能导致系统响应非线性。 优化建议: 1. **重新整定PID参数**:采用系统化的整定方法: - 将I和D参数归零,只使用P控制。 - 逐渐增加P直到系统开始振荡(临界增益$K_u$),记录此时的振荡周期$T_u$。 - 根据齐格勒-尼古拉斯方法,对于PI控制器:$K_p=0.45K_u, T_i=0.83T_u$(即$K_i=K_p/T_i$)。 - 然后加入微分项,$K_d=K_p \cdot T_d$,其中$T_d$通常取$T_u/8$。 2. **降低控制周期**:尝试将控制周期缩短到10ms甚至5ms(注意定时器中断的能力)。修改定时器配置,提高中断频率。 3. **改进速度计算**: - 使用更精确的速度计算方法,例如M法测速(在固定时间内计数)或T法测速(测量脉冲之间的时间)。用户目前使用的是M法(20ms内计数)。 - 考虑使用滑动平均滤波或低通滤波处理速度反馈值。 4. **调整死区补偿策略**:死区补偿可能导致电机在低速时反复启停。可以尝试: - 使用连续的死区补偿函数,例如: ```c if (duty > 0) duty += MIN_DUTY; else if (duty < 0) duty -= MIN_DUTY; ``` 这样当输出很小时,也能保证超过死区。 5. **摩擦补偿**:在控制输出中加入与速度方向相反的摩擦力补偿值。例如: ```c // 摩擦补偿(库仑摩擦) float friction_compensation = 0.0f; if (speed_l > 0.1f) { friction_compensation = FC; // 正补偿 } else if (speed_l < -0.1f) { friction_compensation = -FC; // 负补偿 } duty_l += friction_compensation; ``` 其中FC需要通过实验确定。 6. **前馈控制**:引入速度前馈和加速度前馈,提高系统响应速度。公式如下: $$ u_{ff} = K_v \cdot v_{target} + K_a \cdot a_{target} $$ 其中$v_{target}$是目标速度,$a_{target}$是目标加速度(可由目标速度差分得到),$K_v$和$K_a$为前馈增益。 7. **检查硬件**: - 确保电机和编码器连接可靠,无接触不良。 - 检查电源电压是否稳定,电机启动时是否有压降。 具体代码修改示例: 1. **速度滤波**: 在`encoder_update`函数中计算速度后,进行滤波: ```c // 低通滤波:new_speed = alpha * current_speed + (1-alpha) * last_speed #define ALPHA 0.3f // 滤波系数,0~1之间,越小越平滑 static float last_speed_l = 0, last_speed_r = 0; speed_l = ALPHA * speed_l + (1-ALPHA) * last_speed_l; last_speed_l = speed_l; speed_r = ALPHA * speed_r + (1-ALPHA) * last_speed_r; last_speed_r = speed_r; ``` 2. **修改控制周期**: 修改定时器配置,将定时器中断周期改为10ms(假设原为20ms): ```c // 原代码可能是20ms中断一次,现在改为10ms DL_TimerA_setPeriod(TIMER_0_INST, DL_TimerA_calculatePeriodForUs(TIMER_0_INST, 10000)); // 10000us = 10ms ``` 3. **加入前馈控制**: 在PID计算后,加入前馈项: ```c // 假设可以计算目标加速度(这里用一阶差分近似) static float last_target_speed_l = 0; float target_acc_l = (target_speed_l - last_target_speed_l) / time_period; // time_period为控制周期,单位秒 last_target_speed_l = target_speed_l; // 前馈项计算(需要调试Kv和Ka) float ff_l = Kv_l * target_speed_l + Ka_l * target_acc_l; // 最终输出 = PID输出 + 前馈 duty_l = duty_l_pid + ff_l; ``` 4. **摩擦补偿**:如上所述。 调试步骤建议: 1. 先只使用P控制,调整P使系统稳定(不振荡)且稳态误差在可接受范围。 2. 加入积分项,消除稳态误差。 3. 加入微分项,抑制超调。 4. 加入前馈,提高响应速度。 5. 加入摩擦补偿,改善低速性能。 注意:每次只调整一个参数,并观察效果。 如果以上方法仍不奏效,可能需要考虑机械结构问题(如轮子打滑)或编码器安装问题。 引用[4]中提到的智能小车设计也强调了控制系统的稳定性,可以参考其控制策略。 最后,建议用户通过串口实时输出速度曲线(左轮速度、右轮速度)和目标速度,以便直观分析问题。 相关问题: 1. 如何通过实验测量电机的摩擦系数? 2. 齐格勒-尼古拉斯整定法的具体步骤是什么? 3. 编码器测速有哪些方法?各有什么优缺点? 4. 如何设计一个低通滤波器来平滑速度信号? 5. 前馈控制在电机速度控制中如何实现?</think>### 电机速度环控制不平滑的原因分析及优化方案 #### 1. **PID参数整定不当**(核心问题) 即使P参数调为0.5仍不理想,说明存在以下深层问题: - **积分饱和现象** 当$K_i$过大时,积分项会累积误差导致输出突变: $$ u(t) = K_p e(t) + \underbrace{K_i \int_0^t e(\tau)d\tau}_{\text{饱和危险}} + K_d \frac{de(t)}{dt} $$ 表现为:电机加速时突然过冲,减速时卡顿。 - **微分噪声放大** 编码器脉冲抖动会被微分项放大,导致PWM剧烈波动[^3]: ```c // 原始微分计算(噪声敏感) float derivative = (error - prev_error) / dt; ``` - **参数耦合问题** 左右轮PID参数相同但机械特性存在差异,需独立调参。 #### 2. **死区补偿策略缺陷** 当前死区处理会引发阶跃突变: ```c // 当前代码(硬切换) if (duty_l > 0 && duty_l < MIN_DUTY) duty_l = MIN_DUTY; ``` 这会导致低速时在`0→MIN_DUTY`间跳跃,产生"抽搐"现象。 #### 3. **速度计算误差** 编码器处理存在两个关键问题: 1. **采样不同步** 在`__disable_irq()`期间丢失脉冲 2. **分辨率不足** 每圈364脉冲,20ms采样周期下: $$ \text{最小可测速度} = \frac{1}{364} \times 204.1\text{mm} \times 50\text{Hz} \approx 28\text{mm/s} $$ 低速时量化误差明显[^1] #### 4. **控制周期过长** 20ms控制周期(50Hz)无法响应电机动态: $$ \text{电机电气时间常数} \tau \approx 10-30ms $$ 需满足:**控制频率 > 5/τ** → 至少100Hz --- ### 系统优化方案 #### 1. **PID算法升级** ```c // 改进PID实现(带滤波和抗饱和) float PID_Update(PID* pid, float target, float actual) { float error = target - actual; // 低通滤波微分项(α=0.3) float deriv = 0.3f * (error - pid->prev_error) / 0.01f + 0.7f * pid->prev_deriv; // 积分抗饱和 pid->integral += pid->Ki * error; if (pid->integral > pid->max_output) pid->integral = pid->max_output; else if (pid->integral < -pid->max_output) pid->integral = -pid->max_output; // 计算输出 float output = pid->Kp * error + pid->integral + pid->Kd * deriv; // 更新状态 pid->prev_error = error; pid->prev_deriv = deriv; return output; } ``` #### 2. **死区平滑处理** 采用连续过渡函数: ```c // 平滑死区补偿(推荐) float deadzone_compensation(float duty) { const float min_duty = 15.0f; if (fabs(duty) < 1e-3) return 0; return duty + (duty > 0 ? min_duty : -min_duty); } ``` #### 3. **编码器优化措施 1. **硬件级改进** - 改用正交编码模式(4倍频→1456脉冲/圈) - 增加光耦隔离防干扰 2. **软件优化** ```c // 精确速度计算(避免中断丢失) void update_speed() { static int32_t last_count_l = 0; int32_t delta = enco_l - last_count_l; // 原子操作读取 speed_l = (delta * 204.1f) / (364.0f * 0.01f); // 10ms周期 last_count_l = enco_l; } ``` #### 4. **控制频率提升** 将定时器周期改为10ms(100Hz): ```c DL_TimerA_setPeriod(TIMER_0_INST, DL_TimerA_calculatePeriodForUs(TIMER_0_INST, 10000)); // 10ms ``` #### 5. **参数整定建议流程 1. 设`Kp=0.5, Ki=0, Kd=0` 2. 增大`Kp`至出现轻微振荡→记为$K_u$ 3. 测量振荡周期$T_u$ 4. 按Ziegler-Nichols法设置: $$ \begin{align*} K_p &= 0.6K_u \\ K_i &= 1.2K_u/T_u \\ K_d &= 0.075K_uT_u \end{align*} $$ 5. 左右轮独立调参(负载不同) --- ### 调试验证方法 1. **数据监测** 通过UART实时输出: ```c printf("L:%.1f/%.1f R:%.1f/%.1f\n", speed_l, target_speed_l, speed_r, target_speed_r); ``` 2. **阶跃响应测试** ```c // 在main循环中 static uint32_t counter = 0; if(counter++ == 500) { // 5秒后加速 target_speed_l = target_speed_r = 200.0f; } ``` 3. **摩擦补偿实验** 测量静摩擦系数: ```c float F_c = 0; while(motor_starts_moving()) { F_c += 0.5; // 增加PWM直到电机转动 Set_Speed(0, F_c); } ``` > 实验表明,经上述优化后速度波动可降低70%以上[^4]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值