搞PLC项目这么多年,我越来越觉得“模拟环境”是这个行业里最值钱的东西之一。尤其像城轨自动售票机这种系统,直接上手现场设备不现实,成本高、风险大,但用S7-200 PLC配合MCGS触摸屏做一套按比例缩放的模拟控制模型,不光能完整走通自动售检票的核心流程,还能把梯形图程序、接线、IO分配这些基本功练扎实。
这个项目我前前后后完整做过一遍,从硬件选型到梯形图逻辑,再到MCGS组态画面联动调试,踩了不少坑,也沉淀了一套可以直接复用的思路。这篇就把整个项目的关键环节拆开讲透,涉及IO分配表、接线图设计、梯形图状态机、组态变量映射以及联调时的典型问题。想搞懂自动售票机控制逻辑的,或者正在做PLC相关课设、毕设的朋友,这篇应该能帮你少走不少弯路。
1. 需求拆解:自动售票机的核心控制流程
1.1 从真实AFC系统里提取的控制边界
城轨自动售检票系统(AFC)在真实场景下是一个非常庞大的机电一体化系统,包含票务管理、现金处理、车票发售、进出站闸机、清分结算等多个子系统。咱们做PLC模拟项目,不需要也不可能复刻整个AFC,关键是提取出“售票机”这个核心终端设备的控制逻辑,再用PLC的思维方式重新建模。
我从真实设备中拆分出的核心控制功能包括这几块:票种选择、票价计算、投币检测、余额累计、出票执行、找零执行、紧急停止。这七个功能足以构成一个完整的控制闭环,而且每一个在PLC里都有非常典型的实现方式。
票种选择对应按钮输入和状态切换,票价计算对应整数运算指令,投币检测对应传感器脉冲计数,余额累计对应累加寄存器,出票和找零分别对应电机控制和电磁阀脉冲控制,紧急停止对应全局复位逻辑。可以说,这个模拟项目麻雀虽小,五脏俱全,PLC的核心编程手段基本都能覆盖。
1.2 控制状态机的定义
在设计梯形图之前,我习惯先把整个控制过程用状态机的方式描述出来。这样后面写程序的时候,脑子里始终有一张清晰的流程图,不会写着写着逻辑就乱了。
自动售票机的控制状态可以划分为五个基本状态:待机状态、选票状态、投币状态、出票找零状态、完成状态。每个状态的进入条件和退出条件必须明确,否则梯形图里很容易出现“多个条件同时满足、输出互相打架”的情况。
| 状态 | 进入条件 | 执行动作 | 退出条件 |
|---|---|---|---|
| 待机 | 上电初始化/完成状态结束 | 显示欢迎界面,等待操作 | 检测到票种选择按钮按下 |
| 选票 | 票种按钮按下 | 锁定票种,计算并显示票价 | 投币传感器首次触发 |
| 投币 | 投币口检测到硬币 | 余额累加,实时刷新显示 | 余额大于等于票价并确认出票 |
| 出票找零 | 余额满足票价 | 出票电机运转,找零电磁阀动作 | 出票检测到位、找零完成 |
| 完成 | 出票找零结束 | 清零本次交易数据 | 回到待机状态 |
这个状态机看起来简单,但真正映射到PLC梯形图里时,是需要用中间继电器或内部辅助继电器来“锁存”当前状态的。比如选票状态,我用一个M0.1表示,当票种按钮I0.1触发且当前处于待机状态M0.0时,M0.1置位;而投币状态M0.2的置位条件,必须是M0.1已经置位且投币传感器I0.2产生脉冲。这样每个状态都有明确的“前一状态+触发条件”双重约束,梯形图的逻辑才会严谨。
1.3 输入输出信号的总线规划
状态机定下来之后,紧接着就是IO信号的总线规划。这一步很多人会忽略,直接凭感觉分配地址,结果画接线图的时候发现地址和端子对不上,或者程序里用到的地址和实际硬接线完全不一致,调试时非常痛苦。
我这个项目的IO分配思路是:输入信号按照“操作类→检测类→安全类”的顺序排列,输出信号按照“执行机构→指示类→声音类”的顺序排列。这样做的好处是,现场接线和程序维护时,一眼就能看出某个地址大致是什么用途。
输入信号包括:启动按钮(常开)、停止按钮(常闭)、单程票选择按钮、普通票选择按钮、优惠票选择按钮、投币检测传感器、出票检测传感器、紧急停止按钮。输出信号包括:出票电机正转继电器、找零电磁阀继电器、运行指示灯、报警指示灯、蜂鸣器。每个信号我都预留了备用点,方便后续扩展功能或者处理突发情况。
2. 硬件规划:IO分配、接线与通讯配置
2.1 S7-200 IO分配表与地址规划
我用的是S7-200 CPU226,自带40个数字量IO,做这个模拟项目绰绰有余,而且留出了大量扩展空间。具体的IO分配表如下:
| 地址 | 信号名称 | 类型 | 说明 |
|---|---|---|---|
| I0.0 | 启动按钮 | 数字量输入 | 系统上电启动 |
| I0.1 | 停止按钮 | 数字量输入 | 系统停止(常闭) |
| I0.2 | 单程票选择 | 数字量输入 | 按下选择单程票 |
| I0.3 | 普通票选择 | 数字量输入 | 按下选择普通票 |
| I0.4 | 优惠票选择 | 数字量输入 | 按下选择优惠票 |
| I0.5 | 投币检测 | 数字量输入 | 光电传感器,检测投币动作 |
| I0.6 | 出票检测 | 数字量输入 | 光电传感器,检测票卡是否到达出票口 |
| I0.7 | 紧急停止 | 数字量输入 | 紧急情况下切断输出 |
| Q0.0 | 出票电机继电器 | 数字量输出 | 驱动出票电机运转 |
| Q0.1 | 找零电磁阀继电器 | 数字量输出 | 驱动找零机构动作 |
| Q0.2 | 运行指示灯 | 数字量输出 | 绿色指示灯 |
| Q0.3 | 报警指示灯 | 数字量输出 | 红色指示灯/蜂鸣器 |
这里有一个需要特别强调的细节:停止按钮和紧急停止按钮我建议接常闭触点,而不是常开触点。原因很简单,如果接常开,一旦按钮接线脱落或者断线,系统是察觉不到“停止”信号的;而接常闭的话,断线会被PLC识别为停止信号,属于“失效安全”设计思路。这一点在工业现场是默认的常识,但很多新手恰恰栽在这里。
2.2 接线图设计的关键细节
接线图是整个项目里最容易被“草草了事”的部分,但恰恰是出问题最多的环节。我按照传感器、输出驱动、供电三个部分分别说。
传感器接线方面,投币检测和出票检测我选的都是NPN常开型光电传感器,24V直流供电。NPN传感器的输出端在检测到物体时输出低电平,所以PLC的公共端(1M)必须接24V正极,这样才能在传感器导通时形成一个从正极经过内部到输入的电流回路。如果你用了PNP传感器却不改公共端接法,输入信号永远等于0,项目压根跑不起来。
输出驱动方面,PLC的输出继电器触点容量一般只有2A,直接驱动电机和电磁阀风险很大,所以我在中间加了一层继电器隔离。每个输出对应的中间继电器线圈电压24V,触点容量5A,这样即使执行机构发生短路,损坏的也只是中间继电器,不会烧掉PLC的输出模块。另外,电磁阀这类感性负载在断电瞬间会产生很高的反向电动势,必须在继电器线圈两端反向并联一个续流二极管,否则很容易干扰PLC的电源,甚至导致程序跑飞。这个二极管极性不能接反,接反了等于短路。
电源配置方面,我用了两个独立的24V开关电源,一个给PLC和传感器供电,一个给中间继电器和执行机构供电。这么做不是为了显得专业,而是非常实际的考虑:电机启动瞬间的电流冲击和电磁阀开关时的干扰,如果和PLC共用电源,会让PLC的24V电压出现剧烈波动,严重的会导致PLC死机或者通讯中断。分开供电后,这类问题基本消失。
2.3 MCGS触摸屏与S7-200的通讯配置
MCGS触摸屏和S7-200之间的通讯,走的是PPI协议。这个协议是西门子专门为S7-200系列设计的点对点通讯协议,在MCGS的设备组态里有现成的驱动,不需要自己写通讯程序,但有几个参数必须对齐,否则通讯就是建立不起来。
第一是通讯端口参数。我用的MCGS触摸屏是COM口连接,COM口参数必须设置为:波特率9600、数据位8位、无校验、停止位1位。这个参数必须和S7-200里的PPI通讯参数完全一致。S7-200的通讯端口参数是在系统块里设置的,默认波特率往往不是9600,一定要通过Micro/WIN软件先确认并修改。
第二是PLC站号。S7-200的PPI站号默认是2,而MCGS设备组态里也要把这个站号设置为2,两者必须对应。如果PLC站号被改过而触摸屏不知道,通讯就会一直处于超时状态。
第三是数据映射关系。MCGS里建立变量时,要勾选“通道处理”和“读写类型”。从PLC读取的数据,比如余额、票价,需要把数据类型和PLC里的寄存器匹配上。S7-200的V区寄存器是字节寻址的,但MCGS里可以直接按字(16位)读取VW地址;M区寄存器按位读取M地址时,要明确是M0.0到M0.7这样一位一位映射,还是直接按字节读取MB0。这里我建议用VW字变量存储数值,用M位变量存储开关状态,两类变量分开建,逻辑上会清晰很多。
3. 梯形图程序实现:状态机与核心逻辑
3.1 程序整体架构与模块划分
梯形图程序最忌讳的是把所有逻辑都堆在OB1主程序里,写到后面自己都找不到某个网络在哪里。我习惯把程序按功能划分成四个子程序:初始化子程序、投币计数子程序、出票找零子程序、报警处理子程序,主程序只负责调用和状态切换。
用西门子S7-200的编程软件Micro/WIN,每个子程序是一页独立的程序段,用SBR指令调用。主程序的逻辑就简洁很多:上电调用初始化子程序,根据当前状态决定是调用投币计数子程序还是出票找零子程序,紧急停止条件满足时无条件跳转到报警处理。
这种模块化划分带来的好处是非常直接的:调试时如果出票逻辑有问题,我只需要打开出票找零子程序,而不是在几百行的梯形图里翻来翻去。而且每一个子程序都可以单独强制输入、观察输出,排查效率高很多。
3.2 核心逻辑一:投币累计与票价比较
投币累计是售票机的核心数据逻辑。使用S7-200的整数运算指令:ADD_I整数加法和比较指令。
投币检测传感器每检测到一个高频信号(代表投入一枚硬币),PLC就把VW100里的余额寄存器累加一次。为了提高仿真演示效果,我设定每次投币金额为1元,对应的传感器就位信号用I0.5的上升沿来触发累加。用上升沿而不是电平,是为了防止传感器在硬币通过期间持续输出高电平导致重复计数。
实际项目中,硬币识别可能有不同面额,需要多个传感器对应不同的累加值。在模拟项目中,一台传感器定值累加就足够了。
票价信息存储为VW102。选票时根据按下按钮的数据,从3元、4元、2元里选择一个写入VW102。然后执行比较指令:VW100(余额)是否大于等于VW102(票价)。如果条件满足,就把当前状态从投币状态切换到出票找零状态,同时锁定当前票价,防止客户在出票过程中再次选票导致数据错乱。
3.3 核心逻辑二:找零计算与执行
找零计算是自动售票机从“自动售货”变成“自动售票”的关键差异点。计算公式是:找零金额 = 余额 - 票价。用整数减法指令SUB_I把结果存入VW104。如果找零金额为0,则直接跳过找零执行。
找零执行我用的是定时器脉冲控制。一个TON定时器产生一个2秒宽度的脉冲,控制Q0.1找零电磁阀动作。这里有一个很重要的经验:电磁阀动作时间不能太短,否则机械机构还没完全动作完就复位了,硬币会被卡在半路;也不能太长,否则影响下一位乘客使用。需要根据实际机的动作反应时间确定,2秒是我在模拟装置上测试下来比较稳妥的值。
出票执行则是控制Q0.0出票电机继电器吸合,带动一个直流电机运转3秒,模拟票卡从票箱被推送到出票口的过程。同时I0.6出票检测传感器实时监视票卡是否已经到达出票口,一旦检测到票卡到位,可以提前结束电机运转;如果设定的3秒内始终检测不到票卡信号,系统应该判断为卡票故障,转入报警处理。
3.4 状态流转:用中间继电器做状态锁存
梯形图里实现状态机,最常用的手段就是“置位/复位”指令。S7-200的置位指令S和复位指令R配合内部辅助继电器M,可以很方便地实现状态锁存。
待机状态M0.0:上电初始化后置位,此时允许票种按钮输入。选票状态M0.1:当M0.0为ON且任一票种按钮按下,置位M0.1,同时复位M0.0。投币状态M0.2:当M0.1为ON且投币传感器上升沿信号到来,置位M0.2,同时复位M0.1。出票找零状态M0.3:当M0.2为ON且余额大于等于票价,置位M0.3,同时复位M0.2。完成状态M0.4:当出票检测到位且找零时长已到,置位M0.4,执行清零,随后复位M0.4并置位M0.0。
这套逻辑写起来不复杂,但每个状态切换时,必须保证“前一状态”的条件还在,否则会出现状态跳变。比如出票找零状态M0.3,它的前置条件是M0.2已经置位且余额满足,两个条件同时为ON才允许置位。我调试时就看到过一次状态跳变的现象:余额已经满足了,但M0.2还没置位,结果票种按钮的一个新脉冲直接把系统带飞了。解决方案就是在置位条件里加上M0.2的状态位,相当于给状态机加了一把锁。
4. MCGS组态画面设计与联动调试
4.1 组态画面的功能分区与变量映射
MCGS组态软件里,一个完整的监控画面至少要包含状态显示区、操作按钮区、参数显示区、报警提示区四个部分。我设计的售票机画面把整个自动售票机的正面面板搬到了触摸屏上,模拟售货机的用户交互体验。
状态显示区放两个大型指示灯,绿色代表系统运行,红色代表紧急停止或故障。这个指示灯和PLC的Q0.2、Q0.3直接对应。操作按钮区放三个票种选择按钮和一个紧急停止按钮,每个按钮都用一个“位开关”元件,对应PLC的输入点I0.2到I0.7的某个位。
参数显示区放两个数值显示框,一个显示当前余额VW100,一个显示票价VW102。这个数值显示必须设定数据转换方式,因为PLC里存的是二进制整数,MCGS默认按16位无符号数处理,但在组态时你要明确告诉它VW100的数值范围是0到9999,并且在显示时保留整数格式,否则可能会出现负数或者乱码。
报警提示区放一个信息显示窗口,当PLC的M10.0报警继电器置位时,MCGS自动弹出“找零机构故障”或“卡票故障”的提示文字。这个功能需要在MCGS的报警配置里设置“表达式报警”,表达式写M10.0 == 1即可。
4.2 动画组态:让画面“活”起来
MCGS强大之处在于它支持多种动画效果,可以让画面中的元件与PLC变量联动。做自动售票机模拟项目,不把动画做好,就失去了“模拟”的意义。
我在出票口位置放了一个小方块的图形元件,代表票卡,它的水平移动距离与Q0.0出票电机状态关联。当Q0.0为ON时,票卡从票箱位置向右移动到出票口位置,速度可以设置成匀速,持续3秒。这一步看起来简单,但实际组态时要注意:MCGS的动画组态需要在“动画连接”对话框里关联“水平移动”属性,起点和终点值要对应PLC变量Q0.0的0和1两个状态,否则画面上的元件根本不会动。
投币动画类似,用一个硬币形状的元件在投币口有一个垂直下落的效果,触发条件是I0.5的上升沿。由于PLC里的输入点信号是瞬时的,动画可能太快看不清,所以我在硬币下落前加了一个延时显示变量,用PLC内部定时器做一个持续0.5秒的脉冲,映射到MCGS里的“可见度”属性,这样每次投币硬币都会在画面上清晰闪现一次。
4.3 联调顺序与数据一致性核对
MCGS和PLC都调好之后,就是联调阶段。联调我建议遵循“先PLC后触摸屏,先单点后联动”的原则,不要一上来就直接跑完整流程。
第一步,单独给PLC运行程序,用Micro/WIN软件的监控表观察每个输入输出点的变化。按下票种按钮,对应的I0.2到I0.4应该能正常翻转;用手动挡片触发投币传感器I0.5,VW100的余额应该增加。这个过程没有触摸屏参与,可以快速定位PLC程序本身的问题。
第二步,PLC程序确认无误后,启动MCGS通讯,先不看画面动画,直接看MCGS的“设备调试”窗口,确认COM口通讯状态是“正常”,然后看读取到的VW100、VW102数值是否与PLC监控表里的一致。如果数据不一致,优先检查寄存器地址是否映射错位,比如VW100和VW102之间的偏移量是否搞反了。
第三步,数据一致后,再启用画面动画,用触摸屏上的按钮配合实物传感器完整走一遍流程:选票、投币、出票、找零。走到这里如果还出问题,基本都是动画关联或者参数显示格式的问题,回组态里仔细检查每一项设置即可。
4.4 设计画面布局时需要考虑的触摸屏响应问题
MCGS触摸屏本质上是嵌入式系统和组态软件的配合,画面元素过多、动画刷新频率过高时,处理速度会明显下降。
我在设计画面时,所有动画元件都严格控制了数量,总共不超过八个动画关联。数据刷新方面,PLC寄存器数据要传递给MCGS时,在设备组态里设置了采集周期为200毫秒。如果采集周期设得太短,触摸屏会频繁向PLC发起通讯请求,反而挤占PPI总线的带宽,导致通讯拥堵。这个200毫秒是我在项目中反复实验出来的平衡点——对于出票、找零这些动作来说,响应速度完全够用,而且通讯一直很稳定。
5. 调试中的典型问题与解决经验
5.1 传感器抖动导致的票数重复计数
第一次联调时,我发现一个很刁钻的问题:投一枚硬币,MCGS画面上余额增加了3到4次,甚至有时候会误触发票种选择。
排查过程是这样的:先在PLC监控表里观察I0.5的状态,发现传感器的信号在硬币通过的瞬间并不是一个理想的单一脉冲,而是伴随着多次高频抖动的连续信号。这是因为硬币在投币轨道里下落时,会因为重力加速度弹跳,同一个硬币会在光电传感器前面来回切割光线好几次。
在真实AFC设备里,投币检测用的是具有防抖功能的专用传感器,或者通过软件滤波来解决。我在梯形图里用了一个简单的防抖处理:当I0.5检测到上升沿时,先启动一个0.2秒的定时器,在这个定时器计时未完成期间,后续的I0.5信号全部忽略。这样就保证了一次物理投币动作只产生一次有效的计数脉冲。
这个问题的根因在传感器而不在程序,但作为调试者,你不能一味要求硬件零缺陷,更多时候是通过程序逻辑去弥补机械层面的不足,这才是工程思维。
5.2 找零动作与出票动作时序冲突
第二次调试时又遇到一个时序问题:出票电机还在运转的时候,找零电磁阀提前动作了,导致机械结构上卡住了。
原因在于我的梯形图里,出票找零状态M0.3置位后,Q0.0和Q0.1几乎是同时被驱动的。实际上,票卡推送到位和找零机构动作需要有一个先后顺序,先出票、后找零,这样两者的机械动作才不会互相干涉。
解决方案是引入一个顺序控制链:M0.3置位后,先启动出票电机Q0.0,等出票检测传感器I0.6反馈票卡到位信号,并延时0.5秒后,才允许Q0.1找零电磁阀动作。这样相当于在出票和找零之间加了一个“握手确认”的环节,时序冲突彻底解决。
5.3 PPI通讯偶发性中断
联调过程中MCGS偶尔会出现通讯超时的报警,不是一直断,而是间发性丢包。
排查通讯问题我是从这几个方面入手的。检查了通讯线,确认屏蔽层在触摸屏端单端接地,而不是两端都接地,避免地环路对通讯信号的干扰。把PLC的通讯波特率重新确认了一遍,确保和MCGS一致。还有很关键的一点,PLC的通讯端口和编程口是同一个,调试时Micro/WIN软件在线监控和触摸屏通讯争抢同一个端口,引起了冲突。拔掉编程线或者停止在线监控后,通讯就恢复了。
这个问题提示我们,在做联调时一定要避免编程器在线监控和触摸屏通讯同时长时间占用同一个PPI端口,否则会丢包。调试完PLC程序后,最好把编程线断开,只保留触摸屏和PLC的通讯线,让触摸屏独占通讯资源。
5.4 急停后恢复的初始化处理
按照安全规范,自动售票机按下紧急停止按钮后应该立即切断所有输出。但急停解除后,系统如果直接从上一次断点继续运行,往往会出现票卡半卡、找零未完成等中间状态,很不安全。
我的处理方式是,在报警处理子程序里增加一个“急停恢复重初始化”逻辑:当I0.7紧急停止按钮从1恢复为0时,先复位出票找零状态M0.3、投币状态M0.2和所有输出Q0.0至Q0.3,然后调用一次初始化子程序,强制系统回到待机状态M0.0。这样做可以确保每次急停恢复后,售票机都从干净的状态重新开始,既安全又方便演示。
需要注意的是,在这个场景中急停复位后系统虽然回到待机状态,但余额数据和票种数据也应该一并清空,防止上一笔未完成的交易数据污染下一笔交易。所以初始化子程序里不但要复位状态位,还要把VW100和VW102这两个关键数据寄存器清零。
6. 关于梯形图设计习惯与效率的几个体会
6.1 用注释管理长程序
梯形图最怕的就是没有注释。S7-200程序里,我强制自己每个网络都写满注释,写明当前网络的逻辑意图和对应的状态。
网络注释不是写给机器看的,机器看的是指令代码,注释是写给未来的自己看的。这个项目结束三个月后,我回来看程序,如果没有注释根本想不起来M0.2为什么会和定时器T37并联。有注释的情况下,几分钟就能重新掌握程序全貌。
6.2 数值运算统一使用VD还是VW
S7-200的V区寄存器既可做字节操作,也可做字操作。自动售票机的金额数值累计,我在项目里用VW100保存余额、VW102保存票价、VW104保存找零,都是16位字操作。如果涉及更大金额或更复杂的计算,建议升级为VD双字操作,避免溢出。
这里要提醒的是,MCGS组态时寄存器类型要和PLC指令一致。PLC里用字指令写入VW100,MCGS里就按寄存器类型16位有符号/无符号处理;如果PLC改成双字指令写入VD100,MCGS里的寄存器地址也要改成32位。寄存器宽度不一致是通讯数据乱码的常见原因之一,排查时一定要把PLC指令宽度和组态数据宽度串联起来看。
6.3 继电器线圈消弧的备用方案
前面提到中间继电器线圈要反向并联续流二极管,实际项目中如果手边没有二极管,也可以换成阻容吸收电路(一个电阻串联一个电容并联在继电器线圈两端),效果类似。
但是有一点你必须坚持:绝对不能省掉这个吸收电路。我见过一个现场,因为没有加续流二极管,电磁阀每次断电时产生的反向电动势直接打坏了触摸屏的电源模块,维修成本远大于一个二极管的几毛钱。
6.4 实验模型的机械结构建议
如果读者朋友也打算复刻这套模拟售票机,机械设备部分不需要太高精度。我用的是透明亚克力板做外壳,投币口用一个漏斗状通道,硬币落下经过光电传感器,传感器型号是E3F-DS30C4(漫反射式光电开关),价格便宜而且灵敏度可调。
出票电机用的是微型直流减速电机,配合两个橡胶滚轮模拟票卡推送机构。找零机构相对麻烦一点,我直接用了一个电磁铁推杆,通电时把一颗“找零硬币”从储币槽推出,虽然和真实找零机构原理差距较大,但作为教学演示已经足够。
6.5 教学演示模式的附加想法
如果这套模拟售票机是用在教学场景里的,我建议在MCGS画面上加一个“教学演示模式”切换按钮。开启后,PLC自动定时循环演示一遍完整的购票流程:自动选票、自动投币、自动出票、自动找零。这样在课堂上不需要有人手动操作按钮,系统自己就能展示整个运行过程,讲解效果比单纯静态画面好很多。
实现思路很简单:用一个M20.0位变量控制“演示模式”,在这个模式里,梯形图中增加一个周期为20秒的循环定时器,每隔一段时间自动触发一次票种选择信号和投币信号,代替人工按钮输入。其他逻辑完全不变。
这套项目做完之后,我对AFC系统的理解深度和PLC编程的综合能力都上了一个台阶。最关键的一点是,我学会了先想清楚状态机,再写梯形图,而不是一边写一边改。对于想系统掌握S7-200和MCGS联调技巧的人来说,自动售票机这个题目真的是性价比极高的练习目标——它不复杂,但足够完整,从IO分配、接线设计、梯形图逻辑到触摸屏组态、通讯联调,整个PLC项目开发的流程它全部覆盖了一遍。把这套流程走通之后,再去看其他类似的项目,基本都能做到心里有数。