1. 包膜机到底要控什么:先把工艺拆开看
1.1 从一次设备改造说起
我前段时间接手了一个挺典型的项目:某食品厂的旧包膜机想要升级。那台老设备用了十几年的继电器逻辑,加一个单轴步进送膜,封切靠气缸硬顶,温度靠温控表独立工作,整个设备操作起来相当依赖老师傅的手感。客户提的需求也很直接:换一套控制系统,要求送膜长度准、封口温度稳、产量能计数、故障能报警,最好还能在触摸屏上直接改产品规格参数。
我拿到这个需求后,第一反应是这套系统用松下FP-XH搭配FPWIN Pro7来做正合适。但真正开始做的时候才发现,程序架构怎么搭、功能块怎么切、状态机怎么写,每一步都需要提前想清楚,否则写到后面一定会乱。这篇文章就把我这次完整的实践过程拆开来说,从工艺到选型,从架构到功能块,再到现场调试踩过的坑,希望对正在做类似包装设备控制的朋友有点参考价值。
1.2 包膜机的工艺流程拆解
先花点时间把包膜机的工艺流程说清楚,因为控制程序的结构,本质上就是工艺流程的映射。一台典型的热收缩包膜机,大致经历这么几个阶段:
- 产品输送:产品从上游生产线进入,由输送带带到进料位置,光电传感器检测到位。
- 成型与纵封:包装膜从卷筒上拉出,经过成型器将膜折成筒状包裹住产品,纵封加热装置对膜的纵向搭接边进行连续热封。
- 送膜定长:伺服电机驱动送膜辊,按设定长度将膜送出。每送一次膜,就对应一个产品的包装长度。
- 横封与切断:横封刀下降,在相邻两个产品之间的膜上完成横向封口,同时把膜切断,让单个包装分离出来。
- 热收缩:已经封切好的产品进入收缩炉,在炉内高温下,包装膜受热收缩,紧紧贴住产品表面。
- 冷却输出:产品从收缩炉出来,经过自然冷却或风冷后,由出料输送带送走。
这样一套流程,涉及的控制点其实不少。送膜轴要精确定长,横封轴要和送膜动作协调,纵封和横封都要控制温度,炉温更是直接决定收缩效果。再加上启动、停止、急停、复位、报警这些常规逻辑,整个控制系统完全不是一台"简单顺序控制机"能覆盖的。
1.3 控制需求清单
我把这次项目的控制需求整理成了清单,后面写程序也好、做选型也好,都是围绕这些点来展开的:
| 控制对象 | 需求 | 精度/要求 |
|---|---|---|
| 送膜伺服轴 | 定长送膜,每包装周期送一次 | ±0.5mm |
| 横封伺服轴 | 往复运动,配合送膜完成封切 | 位置同步准确 |
| 纵封温度 | 恒定温度控制,保证纵缝封合质量 | ±5℃ |
| 横封温度 | 封切刀温度控制,温度过高会烫穿膜 | ±5℃ |
| 收缩炉温度 | 炉温稳定,保证收缩效果一致 | ±5℃ |
| 主输送带 | 恒速运行,速度与送膜节拍匹配 | 可调 |
| 气缸动作 | 成型器开合、横封刀升降等 | 到位检测 |
| 人机交互 | 参数设定、产量统计、报警显示 | 触摸屏 |
这个需求清单列出来之后,整个控制系统的轮廓就清晰了:至少需要两路脉冲输出控制伺服,至少三路温度采集和PID调节,加上一堆数字量输入输出。接下来就是选型的问题了。
2. 为什么是FP-XH配Pro7:硬件和软件的双重考虑
2.1 硬件层面:FP-XH够用且不过剩
说实话,松下FP系列PLC在包装设备领域的使用率一直不低,FP-XH这个系列在中小型设备里算是很能打的。它最吸引我的几点:
- 内置多路脉冲输出:FP-XH本体自带4路100kHz脉冲输出,可以直接控制伺服/步进。我这台设备用到送膜轴和横封轴,本体就够用,不需要额外配定位模块。
- 内置高速计数:接编码器做反馈很方便,后续如果要做闭环补偿,基础硬件已经有了。
- 程序容量足够大:结构化编程的代码量通常会比传统梯形图略大,因为要定义功能块、变量、数据结构,FP-XH的容量跑这种规模的设备完全没压力。
- 扩展灵活:温度采集需要模拟量输入,FP-XH可以挂扩展模块,温度模块、模拟量模块都有现成的。
这里插一句,选型时别只看当前需求,还要留一点余量。比如我这台设备现在只用到2个轴,但FP-XH有4路脉冲输出,后续客户如果想加一个打标轴或者飞切轴,程序架构不用动,硬件上也接得住。
2.2 软件层面:FPWIN Pro7和GR的本质区别
熟悉松下的朋友知道,松下PLC的编程软件有两大阵营:一个是FPWIN GR,梯形图编程,老工程师用得多;另一个就是FPWIN Pro7,支持IEC 61131-3标准的结构化编程。
很多人有个误解,觉得"Pro7就是用来写ST语言的",其实没那么简单。Pro7带来的是一整套结构化编程思维。传统梯形图程序是一张"大网",所有逻辑铺在同一平面上,触点套触点,线圈串线圈,程序一长,排查问题就像在一堆乱麻里找线头。Pro7则允许你把程序拆成一个个独立的功能块,每个功能块有明确的输入输出接口,内部状态自己管理,外部只通过接口交互,程序结构清楚得多。
打个比方,梯形图程序像是一间"大开间",桌椅板凳全挤在一起;结构化编程像是一栋"有隔间的办公楼",每个部门有自己独立的办公室,部门之间通过指定的门和走廊往来。平时办公没区别,一旦出了问题,结构化编程能立刻定位问题在哪个部门,不用满楼跑。
我这台包膜机的控制逻辑里,送膜轴、横封轴、温度回路、状态机、报警管理,各自逻辑都比较独立,刚好是结构化编程最擅长处理的场景。Pro7可以用结构化文本(ST)写状态机和算法,用梯形图(LD)写简单的逻辑,用功能块图(FBD)组合调用,几种语言混着用,灵活性很高。
3. Pro7程序架构设计:搭好骨架才能盖好楼
3.1 任务规划:把不同实时性的逻辑分开放
Pro7的任务管理方式和传统PLC不太一样,它允许你把程序挂在不同类型的任务下,每个任务有独立的扫描周期。这一点用好了,能让程序的实时性大幅提升。
我这台设备的任务规划是这样的:
| 任务类型 | 执行周期 | 放置内容 |
|---|---|---|
| 初始任务 | 冷启动执行一次 | 变量初始化、功能块初始参数加载 |
| 周期任务1 | 10ms | 急停处理、轴控制、状态机核心逻辑 |
| 周期任务2 | 50ms | 触摸屏通信、数据显示、操作指令解析 |
| 周期任务3 | 200ms | 温度PID计算、温度报警判断 |
为什么这么分?因为轴控制和急停属于"毫秒级响应"的逻辑,必须放在快周期里,慢了就会出问题——比如急停按下去之后伺服还要多跑几十毫秒,这在设备上可能就造成安全事故了。温度环路的时间常数很大,加热器从通电到温度变化要好几秒,用200ms的周期去执行PID计算完全足够,放在慢周期里还能节省CPU资源。
这个任务划分的思路,是我在做这台设备时觉得最值得分享的一点。很多从梯形图转过来的朋友容易犯一个毛病:所有逻辑扔进一个扫描周期里,结果一个温度PID计算就把整个扫描拖慢,轴的响应也变差了。
3.2 功能块划分:按"职责"而不是按"动作"切分
程序拆功能块有个原则:每个功能块只负责一类职责,内部实现细节封装起来,外部通过接口调用。我这次的划分是这样的:
- FB_MachineState:设备整体状态机,管理停止、待机、运行、暂停、报警等状态切换。
- FB_FeedAxis:送膜轴控制,封装回原点、绝对定位、点动、状态反馈。
- FB_CutAxis:横封轴控制,封装往复运动、位置同步、故障处理。
- FB_TempLoop:温度控制回路,输入是热电偶实测温度和设定值,输出是SSR的占空比控制信号。
- FB_Alarm:报警管理,统一收集各处故障信号,生成报警码、触发蜂鸣器和报警灯。
每个功能块的接口设计也很重要。比如FB_TempLoop,它对外暴露的输入只有"使能"和"设定温度",输出只有"当前温度"和"加热输出占空比",内部PID参数、上下限、温度偏差报警逻辑全部封装在块内。这样一来,触摸屏程序只需要读写这几个接口变量,完全不关心内部怎么调的PID,程序间的耦合度非常低。
调试时这个好处特别明显。哪一路温度不对,直接看对应那一路功能块的监控数据,内部变量一览无余,不用像梯形图那样在一大堆线圈里找是哪一段逻辑出了问题。
3.3 变量管理:用UDT把数据"结构化"
Pro7支持自定义数据类型(UDT),这个功能我用得非常多。轴参数、温度参数、设备统计信息,都可以定义成结构体来管理。
比如轴的参数,我是这么定义的:
TYPE ST_AxisParam : STRUCT bEnable : BOOL; // 使能 bHomeDone : BOOL; // 已完成回原点 diTargetPos : DINT; // 目标位置(脉冲) diActualPos : DINT; // 当前位置(脉冲) diSpeed : DINT; // 运行速度(Hz) uiAccelTime : UINT; // 加速时间(ms) uiDecelTime : UINT; // 减速时间(ms) END_STRUCT END_TYPE有了UDT,功能块的接口参数就不需要散成一大堆数据类型,而是一个结构体整体传入。触摸屏要读轴状态,也只需要读取这一个结构体的成员。全局变量的数量被大大压缩,程序的可读性明显提升。
这里我要专门提一个经验:全局变量一定要严格控制。我在这个项目里定了个规矩——只有触摸屏需要读写的数据才放全局变量,其余数据一律留在功能块内部。这样做的直接好处是,程序里不会出现"某个变量在好多地方都被改过"的尴尬情况,排查问题时思路干净很多。
4. 核心功能块的实现:轴、温度、状态机逐个说
4.1 送膜轴:脉冲当量先算清楚
送膜轴是整个设备里定位精度要求最高的部分,膜长差一点点,封切位置就会偏,直接影响包装外观和密封质量。先算脉冲当量,这是一切定位控制的基础。
我这台设备的机械参数:送膜辊直径80mm,伺服电机到送膜辊的减速比5:1,伺服电机编码器分辨率131072脉冲/转(17位增量式/绝对式)。
- 送膜辊转一圈,膜前进距离 = π × 80 ≈ 251.33mm
- 电机要转5圈,送膜辊才转1圈
- 控制器发5 × 131072 = 655360个脉冲,送膜辊转1圈
- 脉冲当量 = 251.33 / 655360 ≈ 0.000383mm/脉冲
这个当量太"碎"了,实际编程时不可能用这么小的单位去设置目标位置。所以我在伺服驱动器里设置了电子齿轮比,把当量放大到一个方便计算的值。比如设置电子齿轮比后,1个脉冲对应0.01mm,那么送膜500mm,目标位置就是50000个脉冲。程序按"0.01mm"为单位做设定和显示,触摸屏上操作非常直观。
程序里调用运动控制功能块,大致是这个样子:
// 送膜长度定位:目标位置500mm,速度80mm/s // 假设每个脉冲=0.01mm,则500mm对应50000脉冲 // 速度80mm/s对应8000Hz脉冲频率 FB_FeedAxis( bExecute := bStartFeed, bHomeDone := bFeedHomed, diTargetPos := 50000, diSpeed := 8000, uiAccelTime := 150, uiDecelTime := 150, bDone => bFeedDone, bBusy => bFeedBusy, bError => bFeedError, diErrorCode => wFeedErrCode );运行周期里,每次送膜完成后会记录实际脉冲数,和理论值做比较。如果偏差超过一定范围,就认为送膜机构有打滑或者机械卡滞,触发报警。这个小逻辑在后期非常有用,客户现场反馈"偶尔包装尺寸不对"的时候,能直接通过历史偏差数据判断问题方向。
4.2 横封轴:往复运动和时序配合
横封轴的运动相对简单一些,但时序配合很关键。横封刀需要在送膜到位后的极短时间内下压封切,然后快速抬起,整个过程要在一个包装节拍内完成。
我的做法是把横封轴设计成"往复运动模式":收到触发信号后,从等待位置加速移动到封切位置,到位后输出封切完成信号给PLC逻辑,再反向回到等待位置。整个运动用轴功能块封装,PLC主逻辑只负责给触发信号和接收完成信号,不需要关心具体伺服怎么走。
时序上有一点容易忽略:横封刀下压封切时,刀头在膜上停留的时间(保压时间)会直接影响封口强度。这个时间太短,封口没封牢;太长,膜会被烫穿或者切断后粘连。我把它做成一个可调参数,在触摸屏上可以设置,范围200~800ms,客户根据膜材质不同自行调整。
实际调试时我踩过一个坑,下面第5章会详细说——气缸和伺服混在一起用时,时序确认很容易出问题。
4.3 温度控制:PID参数怎么调才不"过冲"
这台设备有三路温度:纵封、横封、收缩炉。三路的控制对象和响应特性不同,PID参数也不能一概而论。
先说传感器和输出。温度采集用K型热电偶,通过扩展的温度模块接入PLC;输出控制用的是SSR(固态继电器)驱动加热管,PLC输出的是占空比信号,也就是通过在一定周期内控制"通/断"的比例来调节加热功率。
PID参数整定,我是按工程上常用的经验法来的:
- 先纯比例(P):把积分和微分都设成0,逐步加大P值,直到温度围绕设定值出现持续振荡。
- 记录振荡周期和振荡时的P值:取振荡时P值的50%~60%作为最终P值。
- 加入积分(I):积分时间从大到小调整,直到温度最终能稳定在设定值附近且没有静差。积分时间太小会导致持续振荡,太大则消除静差太慢。
- 微分(D)尽量不用或给很小值:热电偶信号本身有一定噪声,微分作用会放大噪声,反而让输出忽大忽小。
具体到我这里,纵封温度设定180℃,横封温度设定190℃~220℃(根据膜材质调整),收缩炉温度设定150℃~180℃。三路的实际PID参数各不相同,但遵循同一个整定方法。
温度控制里还有几个容易忽略的细节:
- 采样周期:我放在200ms的慢周期任务里,对温度环路完全足够。采样周期太快反而会给D作用带来噪声。
- 输出限幅:加热输出占空比需要做上下限限制。比如升温阶段可以100%输出,但在接近设定值时,上限要限制在70%左右,防止过冲。
- 温度报警:温度偏差超过±10℃持续一定时间,要报警。这个延时判断很重要,不然开机升温阶段会误报警,因为从室温到设定值需要好几分钟。
4.4 状态机:设备运行的"交通规则"
状态机是整个程序的主干。设备所有操作逻辑都在状态机的框架下运行,状态切错了,后面的动作就会跟着乱套。
我这台设备的状态定义如下:
| 状态 | 含义 | 进入条件 |
|---|---|---|
| STOPPED | 停止状态 | 上电、按停止键 |
| STANDBY | 待机状态 | 各部分初始化完成,允许启动 |
| RUNNING | 自动运行 | 按启动键,条件满足 |
| PAUSED | 暂停状态 | 运行中按暂停 |
| ALARM | 报警状态 | 任一故障触发 |
ST语言写状态机非常顺手,基本框架就是一个CASE语句:
CASE byState OF ST_STOPPED: // 停止状态:复位所有输出 // 条件满足后切换到待机 IF bInitComplete AND NOT bEmergencyStop THEN byState := ST_STANDBY; END_IF ST_STANDBY: // 待机:等待启动指令 IF bStartButton THEN // 检查各轴已回原点 // 检查温度在允许范围内 IF bAllHomeDone AND bTempReady THEN byState := ST_RUNNING; END_IF END_IF ST_RUNNING: // 自动运行:周期执行送膜、封切逻辑 IF bStopButton THEN byState := ST_STOPPED; ELSIF bPauseButton THEN byState := ST_PAUSED; ELSIF bAlarmActive THEN byState := ST_ALARM; END_IF ST_PAUSED: // 暂停:轴保持,温度继续工作 IF bResumeButton THEN byState := ST_RUNNING; END_IF ST_ALARM: // 报警:停止所有运动输出,保留温度控制(防止误切/误停) IF NOT bAlarmActive AND bResetButton THEN byState := ST_STANDBY; END_IF END_CASE状态机里有一个设计细节我特别想强调:报警状态下,温度回路仍然保持工作。因为如果炉温报警就全停加热,设备长期停机时温度会掉得很低,重新升温又要很久。而横封刀处于"压住膜"的位置时,如果温度掉到太低,膜会和刀粘在一起,处理起来非常麻烦。所以我的报警恢复策略是:运动轴全停,温度保持恒温。
4.5 各功能块之间的调用关系
功能块之间不是互相"乱调"的,而是有清晰的层级关系。我的程序里,最上层是主程序和状态机,状态机负责调度各功能块。送膜轴、横封轴、温度回路、输送控制,都在状态机的不同状态下被调用。报警功能块则是"旁路式"的,随时接收来自各功能块的故障信号,一旦有故障就向状态机报告,由状态机统一决定如何处理。
这种"主从+旁路"的结构,好处是故障处理路径非常清晰。轴出了问题,报警块收到信号,报告给状态机,状态机做决策,主程序执行输出。每一条路都是单向的,不会出现"报警块直接改轴参数"这种绕来绕去的现象。
5. 现场调试记录:几个坑和我的处理办法
5.1 伺服脉冲受干扰,送膜长度忽长忽短
调试第一天就遇到了一个很头疼的问题:设备空跑的时候一切正常,一启动主输送带,送膜长度就开始不准。有时候偏差几毫米,有时候偏差十几毫米,完全没有规律。
排查过程我按"由简到繁"做了几步:
- 先怀疑机械打滑,检查送膜辊和驱动机构,没有发现问题。
- 再用示波器看伺服驱动器的脉冲输入端子,发现输送带启动时,脉冲信号上叠加了大量毛刺和尖峰,这就是干扰。
- 顺着干扰源排查,发现伺服脉冲线当时走的线槽和动力线挨在一起,输送带电机启动瞬间的大电流在线上感应出了噪声。
处理办法也不复杂:伺服脉冲线换成屏蔽双绞线,屏蔽层在PLC侧单端接地;线槽里和动力线拉开距离,不强行捆在一起;PLC输出端加了阻容吸收电路,把高频毛刺吸收掉。处理后用示波器复查,波形干净了,送膜长度恢复正常。
这件事给我提了个醒:结构化和软件做得再好,硬件布线不规范照样会出问题。后来我给类似项目做电气设计时,都会专门画一张"弱电信号线与动力线分离"的布线图给现场接线人员参考。
5.2 回原点位置每次都不一样
送膜轴和横封轴都需要回原点。调试时发现,回原点动作执行多次后,每次停下来的位置都会有2~3mm的偏差。对于横封轴来说,这个偏差还能接受,但对送膜轴来说,原点就是送膜长度的基准点,差了2mm意味着每次包装的封切位置都在变。
问题根源在回原点的逻辑上。最初我写的回原点流程很简单:先以高速找原点开关,遇到开关信号后立即减速停止。但机械结构是有惯性的,从收到开关信号到真正停下来,设备已经往前冲了一段距离。而伺服编码器在"找开关"过程中是只走脉冲计数的,没有做位置捕获,所以每次的惯性位移都会有细微差异。
解决办法是改用"双段回原点":
- 先高速寻找原点开关,碰到开关后立即反方向低速离开。
- 再次低速接近原点开关,这次在碰到开关信号沿时,马上让伺服进入位置锁定状态。
- 回原点完成后,再走一个固定偏移量,把机械原点修正到电气原点。
这样处理后,回原点位置的重复精度到了0.1mm以内。这个思路同样适用于其他需要高精度回原点的设备。
5.3 横封温度过冲,烫穿包装膜
调试横封温度时,我把设定温度调到190℃,结果实测温度直接冲到215℃,膜都烫穿了才回到设定值附近。这就是典型的PID参数没调好导致的过冲。
我重新按经验法整定了一遍。先纯P,发现在P值到某数值时温度开始持续振荡,周期大约40秒;然后确定P为振荡值的55%;再加入积分,积分时间从300秒开始往下调,最终稳定在180秒左右;微分时间没有启用,因为热电偶信号噪声偏大,D作用会让输出抖动。
另一个重要措施是加了输出限幅:升温阶段全功率加热,但一旦温度达到设定值的85%,输出占空比就限制在60%。这样就让升温曲线在接近目标之前"收一脚油门",过冲幅度大幅减小。最终实测横封温度稳定在190±2℃以内,完全满足工艺要求。
5.4 气缸动作未到位就开始送膜,膜被切歪
设备上有两个气缸动作:成型器的开合和横封刀的辅助压紧。初次联调时发现,偶尔会出现膜切歪的情况,不是每包都歪,是隔一会儿就歪一包。
排查逻辑卡了很久,最终定位到是时序竞争问题:气缸电磁阀得电后,程序立刻认为"气缸已经到位",马上触发送膜轴动作。但实际上气缸从得电到真正到位是有动作时间的,大约80~150ms,这个时间里膜的位置还在变化,送膜轴一旦启动,膜就会在成型器没有完全闭合的状态下走偏,切出来就是歪的。
解决办法很简单但也很有代表性:所有气缸动作后,必须等待到位开关信号确认,才能触发下一步动作。同时给每个气缸动作加上超时监控——如果电磁阀得电后500ms内尚未收到到位信号,就触发"气缸动作超时"报警,而不是让设备带着隐患继续跑。
这里我还学到一个经验:气缸到位开关尽量用磁性开关加机械双重确认,不要只靠程序延时去估算。程序延时是在"假设一切正常"的前提下设计的,一旦气缸掉压或者卡滞,延时就会造成设备损坏。把主动权交给传感器反馈,程序只负责判断"是否到位",是最稳妥的。
6. 这次实践的复盘:结构化编程真正的价值在哪
整个项目从方案设计到现场交付,大概花了六周时间,其中有接近两周是在现场调试。这个速度比我预想的要快不少,而且过程中程序的修改、功能块的复用,给我留下了很深的印象。
6.1 调试效率的提升是切身体会
传统梯形图程序调试时,最大的痛点就是"不知道问题出在哪"。一个输出不动作,可能是输入信号没到,可能是中间继电器逻辑没满足,也可能是程序里某个地方把它复位了,你要顺着逻辑一条一条往下找。而结构化编程下,每个功能块的责任边界非常清晰,轴出了问题看轴功能块,温度出了问题看温度功能块。
举个真实例子:现场有一次纵封温度波动很大,正常情况下这个温度是很稳定的。梯形图时代,我要先把和纵封温度相关的所有逻辑一个个翻出来。但这台设备我只用了不到十分钟——把温度功能块的内部监控数据打开,发现PV值本身就有较大波动,而输入输出侧其他参数都正常,于是很快判断是热电偶接线端子接触不良导致信号跳动。换掉端子后恢复正常。整个过程完全不需要"大海捞针",因为每一根针都在它应该在的抽屉里。
6.2 程序复用在下一个项目里直接兑现
这个项目交付三个月后,客户又订了一台不同的包膜设备,结构类似但横封机构不一样,而且多了一个打码工位。我拿到需求后,直接把上一台设备的程序复制过来,状态机、送膜轴、温度回路、报警管理这些功能块基本原封不动,只修改了横封轴的运动参数,新增了一个打码轴的调用。程序调试时间从第一台的六周压缩到了十天左右。
这就是结构化编程最直接的商业价值。对做非标设备的朋友来说,每个项目看着都不一样,但细拆下来,很多功能块是共通的——轴控制、温度控制、状态机、报警管理,几乎每台设备都要用。把这些做成标准化功能块库,沉淀下来,之后的项目就是在"搭积木"而非"从零造轮子"。
6.3 后续可以扩展的方向
这台设备目前已经稳定运行了大半年,客户反馈良好。如果后续要继续挖潜力,我认为有几个方向值得考虑:
- 加一个物联网数据采集模块,把设备的产量、温度曲线、报警记录上传到远程平台,客户能直接看到设备的运行状态,也能提前发现潜在故障。
- 建立一个标准化功能块库,把轴控制、温度控制这些模块做成带文档的通用库,新项目直接调用,减少重复开发。
- 如果设备后续需要更高的同步精度,可以考虑升级到总线型伺服系统,把脉冲控制改为实时总线控制,多轴联动能力会强很多。
我个人的体会是,做设备控制这一行,能写通的程序不少,能"写清爽"的程序不多。结构化编程给我最大的收获不是学会了一个软件、一种语言,而是建立了"先想清楚再动手"的习惯。工艺拆解、架构设计、功能划分,这些事情看起来费时间,实际上后面省下来的时间和精力远远超过前期投入。如果你也正在从梯形图过渡到结构化编程,不妨找一台复杂度适中的设备练练手,跑完一个完整项目,你会有很直观的感受。