代码整理-网站灰度(黑白)效果

本文介绍了如何使用CSS和JavaScript在特定日期使网站首页变为黑白,通过判断页面路径名和时间范围来动态添加黑白样式,以纪念逝去的伟人。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说明

  • 某些特定的日子你的网站可能需要首页变为黑白的效果以悼念某个伟人的逝世

操作步骤

核心思路

  • css定义一个固定的class
  • js判断当前页面的URL中的pathname是不是首页,如果是首页
    • 定义一个开始时间戳、一个结束时间戳,比如某一天的0点到24点
    • 获取当前时间戳,如果当前时间戳在开始和结束时间内,则给html添加定义好的class

代码

  • css
    .html-gray {
      filter: grayscale(100%);
      -webkit-filter: grayscale(100%);
      -moz-filter: grayscale(100%);
      -ms-filter: grayscale(100%);
      -o-filter: grayscale(100%);
      -webkit-filter: grayscale(1);
    }
    
  • js
    // 首页黑白效果
    jQuery(document).ready(function ($) {
        var pathname = window.location.pathname;
    
        // 只有首页显示
        if (pathname === '/') {
            const startTime = 1669824000000;
            const endTime = 1669910399000;
            const nowTime = new Date().getTime();
            if (nowTime > startTime && nowTime < endTime) {
                // 兼容IE9及以下和谷歌
                $('html').addClass('html-gray');
                $('head').append('<style>*{filter:gray; color:gray;}</style>');
            }
        }
    });
    
<think>嗯,用户让我帮忙写一个八路灰度传感器循线的PID代码。首先,我需要理解用户的需求。他们可能是在做一个自动循线的小车,比如智能车或者机器人比赛中的项目。八路灰度传感器意味着有八个模拟输入,用来检测地面的线条,通常排列成一排,覆盖较宽的检测范围,这样能更精确地判断小车相对于线的位置。 接下来,用户提到了PID控制,所以需要实现一个PID算法来调整小车的转向,保持沿着线行驶。PID控制器需要根据传感器的读数计算出误差,然后输出控制量,通常是电机的PWM信号,来调整方向。 首先,我应该考虑如何读取八个传感器的数据。通常这些传感器会返回模拟值,可能需要先进行校准,确定阈值,区分黑线和白地。但用户可能只需要基本的代码结构,所以可以先假设已经校准好了,或者直接读取原始值。 然后,确定当前的位置误差。八路传感器通常会被赋予不同的权重,比如中间两个传感器权重为0,左右各三个传感器分别赋予正负权重,这样可以根据哪个传感器触发来计算偏离中心的程度。例如,假设传感器从左到右编号为0到7,当中间的传感器3和4检测到线时,误差为0;如果左边的传感器2触发,误差可能是-1,更左边的可能是-2,右边同理。这样误差值可以用来判断偏离方向。 不过,更常见的方法是使用加权平均法。比如每个传感器对应一个位置值,比如从左到右的位置是-3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,然后根据哪些传感器被触发(比如数值超过阈值),计算加权平均值作为当前的位置误差。例如,如果只有中间的传感器4(位置0.5)触发,误差就是0.5;如果左边两个传感器触发,比如位置-3.5和-2.5,平均值就是-3,这可能代表较大的左偏。 不过,实际中可能需要根据传感器排列的实际物理距离来设定位置权重。比如每个传感器的间距相同,所以位置权重可以是-4到+3,或者其他对称的值,确保中心误差为0。这部分需要用户根据实际硬件布局调整,但代码中需要给出一个示例的权重数组。 接下来是PID的计算。PID需要比例、积分、微分三个参数。比例项是当前误差乘以Kp,积分项是误差累积乘以Ki,微分项是当前误差与上次误差的差值乘以Kd。然后总和就是输出控制量,用来调整转向,比如控制左右轮的速度差。 在代码结构上,可能需要循环读取传感器数据,计算误差,然后应用PID算法,最后输出控制量。如果是Arduino之类的平台,可能需要使用analogRead函数读取每个传感器,然后处理这些数据。 需要注意的是,积分项可能会有积分饱和的问题,所以可能需要限制积分项的大小,或者加入抗饱和机制。微分项可能需要滤波,避免噪声影响。此外,输出控制量可能需要限制在合理范围内,比如PWM的0-255之间。 另外,用户可能需要知道如何调整PID参数,Kp、Ki、Kd,这通常需要通过实验调试,比如先调Kp,直到小车有反应但震荡,然后加入Kd来减少震荡,最后调整Ki消除静差。 现在,把这些思路整理代码结构。首先定义传感器引脚,读取数据,计算误差,然后PID计算,最后输出到电机。可能需要使用数组存储传感器值和对应的权重。示例代码可能如下: 首先,定义八个传感器的引脚,假设连接到A0到A7: const int sensorPins[8] = {A0, A1, A2, A3, A4, A5, A6, A7}; 然后,定义权重数组,假设传感器从左到右对应的位置权重: float weights[8] = {-3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5}; 读取每个传感器的值,判断是否在黑线上,可能需要设定阈值: int sensorValues[8]; bool lineDetected[8]; for(int i=0; i<8; i++){ sensorValues[i] = analogRead(sensorPins[i]); lineDetected[i] = sensorValues[i] > threshold; // threshold需要预先校准 } 然后计算误差,使用加权平均: float error = 0; int detectedCount = 0; for(int i=0; i<8; i++){ if(lineDetected[i]){ error += weights[i]; detectedCount++; } } if(detectedCount > 0){ error = error / detectedCount; } else { // 没有检测到线,可能需要特殊处理,比如保持上一次误差或停止 } 接下来是PID计算: float Kp = 1.0; // 需要调整 float Ki = 0.0; float Kd = 0.0; static float prevError = 0; static float integral = 0; float derivative = error - prevError; integral += error; float output = Kp * error + Ki * integral + Kd * derivative; prevError = error; 然后,根据output调整电机。比如,如果是差速转向,左轮速度为baseSpeed + output,右轮为baseSpeed - output。需要注意output的范围,可能需要限制在±maxOutput,比如: float maxOutput = 100; // 根据实际情况调整 if(output > maxOutput) output = maxOutput; else if(output < -maxOutput) output = -maxOutput; 然后设置电机速度: int baseSpeed = 150; // 基础速度 int leftSpeed = baseSpeed + output; int rightSpeed = baseSpeed - output; // 确保速度不超过PWM范围(0-255) leftSpeed = constrain(leftSpeed, 0, 255); rightSpeed = constrain(rightSpeed, 0, 255); analogWrite(leftMotorPin, leftSpeed); analogWrite(rightMotorPin, rightSpeed); 当然,这只是一个基本框架,实际中可能需要处理更多情况,比如所有传感器都未检测到线时的处理策略,比如根据上一次的转向方向继续转,或者减速停止。此外,PID参数的调整需要用户根据实际情况进行调试。 另外,可能需要考虑传感器的噪声,比如使用移动平均滤波来处理传感器数据,或者使用数字低通滤波器处理微分项,避免高频噪声影响。 总结代码结构,大致分为以下几个部分: 1. 定义传感器引脚和权重 2. 读取传感器数据并计算误差 3. 计算PID输出 4. 调整电机速度 5. 循环执行以上步骤 需要注意的是,代码中的具体引脚编号、权重、PID参数、电机控制方式等都需要根据用户的硬件连接和实际需求进行调整。因此,在示例代码中需要提醒用户这些部分可能需要修改。 最后,用户可能需要了解如何调试PID参数,可以建议他们先设置Ki和Kd为0,调整Kp直到小车能快速响应但不过冲,然后加入Kd来减少震荡,最后加入Ki来消除稳态误差。</think>以下是一个基于八路灰度传感器循线的PID控制代码框架,包含详细的中文注释和调试建议: ```cpp // ==== 引脚及参数定义 ==== // 假设传感器接在A0-A7,电机驱动使用PWM引脚5、6 const int sensorPins[8] = {A0, A1, A2, A3, A4, A5, A6, A7}; const int LEFT_MOTOR = 5; // 左电机PWM引脚 const int RIGHT_MOTOR = 6; // 右电机PWM引脚 // 传感器位置权重(根据实际安装位置调整) float weights[8] = {-3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5}; // PID参数(需调试) float Kp = 1.2; // 比例系数 float Ki = 0.01; // 积分系数 float Kd = 0.3; // 微分系数 // 运行参数 int threshold = 500; // 灰度阈值(需校准) int baseSpeed = 150; // 基础速度(0-255) int maxOutput = 100; // PID输出限幅 // ==== 变量声明 ==== float integral = 0; // 积分项累计 float prevError = 0; // 上次误差 // ==== 初始化 ==== void setup() { Serial.begin(9600); pinMode(LEFT_MOTOR, OUTPUT); pinMode(RIGHT_MOTOR, OUTPUT); } // ==== 主循环 ==== void loop() { // 1. 读取传感器数据 bool sensorState[8]; for(int i=0; i<8; i++){ sensorState[i] = (analogRead(sensorPins[i]) > threshold); } // 2. 计算位置误差(加权平均法) float error = 0; int activeCount = 0; for(int i=0; i<8; i++){ if(sensorState[i]){ error += weights[i]; activeCount++; } } if(activeCount > 0){ error /= activeCount; // 加权平均误差 } else { // 处理丢线情况:沿用上次误差值或特殊处理 error = prevError * 0.8; // 衰减处理 } // 3. 计算PID输出 integral += error; float derivative = error - prevError; // 积分限幅防止饱和 integral = constrain(integral, -100, 100); // PID公式 float output = Kp*error + Ki*integral + Kd*derivative; // 输出限幅 output = constrain(output, -maxOutput, maxOutput); // 4. 电机控制 int leftSpeed = baseSpeed + output; int rightSpeed = baseSpeed - output; // PWM限幅 leftSpeed = constrain(leftSpeed, 0, 255); rightSpeed = constrain(rightSpeed, 0, 255); analogWrite(LEFT_MOTOR, leftSpeed); analogWrite(RIGHT_MOTOR, rightSpeed); // 5. 更新误差记录 prevError = error; // 可选:添加延时(根据采样需求调整) delay(10); } ``` ### 🛠 关键实现说明: 1. **误差计算**:采用加权平均法 $$ \text{error} = \frac{\sum (\text{weight}[i] \times \text{sensorState}[i])}{\text{activeCount}} $$ 当传感器未检测到线时,使用误差衰减策略 2. **PID公式**: $$ \text{output} = K_p \cdot e(t) + K_i \cdot \int e(t)dt + K_d \cdot \frac{de(t)}{dt} $$ 3. **抗饱和处理**: - 积分项限制在$[-100, 100]$ - 最终输出限制在$[-\text{maxOutput}, \text{maxOutput}]$ ### 🔧 调试建议: 1. **传感器校准**: - 分别测量传感器在黑白区域的读数 - 设置阈值:$ \text{threshold} = \frac{\text{白区最小值} + \text{黑区最大值}}{2} $ 2. **PID参数整定**(按顺序调试): 1. 先设$K_i=0, K_d=0$,增大$K_p$直到出现小幅震荡 2. 加入$K_d$抑制震荡(典型值为$K_p$的0.2-0.5倍) 3. 最后加入$K_i$消除静差(从$K_p$的0.01倍开始) 3. **异常处理优化**: ```cpp // 在丢线处理部分可扩展: if(activeCount == 0){ // 方案1:按最后已知偏差方向搜索 // 方案2:减速旋转搜索 // 方案3:触发紧急停止 } ``` ### 📌 注意事项: 1. 实际安装时需确保传感器间距均匀 2. 电机需差速控制(建议使用电机驱动模块) 3. 建议增加蓝牙/WiFi模块实时调整PID参数 需要根据具体硬件平台(如Arduino、STM32等)调整引脚定义和PWM设置,建议先用串口绘图工具观察误差曲线和输出响应。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值