精华内容
下载资源
问答
  • 帧同步,帧同步什么意思

    千次阅读 2019-04-08 12:57:45
    帧同步,帧同步什么意思 在数字通信时,一般总是以一定数目的码元组成一个个的“字”或“句”,即组成一个个的“群”进行传输的。因此,群同步信号的频率很容易由位同步信号经分频而得出。但是,每个群的开头和末尾...

    帧同步,帧同步是什么意思
    在数字通信时,一般总是以一定数目的码元组成一个个的“字”或“句”,即组成一个个的“群”进行传输的。因此,群同步信号的频率很容易由位同步信号经分频而得出。但是,每个群的开头和末尾时刻却无法由分频器的输出决定。群同步的任务就是在位同步信息的基础上,识别出数字信息群(“字”或“句”)的起止时刻,或者说给出每个群的“开头”和“末尾”时刻。
    群同步有时也称为帧同步。为了实现群同步,可以在数字信息流中插入一些特殊码字作为每个群的头尾标记,这些特殊的码字应该在信息码元序列中不会出现,或者是偶然可能出现,但不会重复出现,此时只要将这个特殊码字连发几次,收端就能识别出来,接收端根据这些特殊码字的位置就可以实现群同步。本节将主要讲述插入特殊码字实现群同步的方法。
    插入特殊码字实现群同步的方法有两种,即连贯式插入法和间隔式插入法。在介绍这两种方法以前,先简单介绍一种在电传机中广泛使用的起止式群同步法。
    起止同步法
    目前在电传机中广泛使用的同步方法,就是起止式群同步法,下面就以电传机为例,简要地介绍一下这种群同步方法的工作原理。
    电传报文的一个字由7.5个码元组成,假设电传报文传送的数字序列为10010,则其码元结构如图1所示。从图中可以看到,在每个字开头,先发一个码元的起脉冲(负值),中间5个码元是信息,字的末尾是1.5码元宽度的止脉冲(正值),收端根据正电平第一次转到负电平这一特殊规律,确定一个字的起始位置,因而就实现了群同步。由于这种同步方式中的止脉冲宽度与码元宽度不一致,就会给同步数字传输带来不便。另外,在这种同步方式中,7.5个码元中只有5个码元用于传递信息,因此编码效率较低。但起止同步的优点是结构简单,易于实现,它特别适合于异步低速数字传输方式。

    连贯式插入法
    连贯式插入法就是在每群的开头集中插入群同步码字的同步方法。作群同步码字用的特殊码字首先应该具有尖锐单峰特性的局部自相关特性,其次这个特殊码字在信息码元序列中不易出现以便识别,最后群同步识别器需要尽量简单。目前已经找到的最常用的群同步码字,就是“巴克”码。
    1.巴克码
    巴克码是一种具有特殊规律的二进制码字。它的特殊规律是:若一个n位的巴克码{X1,X2,X3,…Xn},每个码元 只可能取值+1或-1,则它必然满足条件
    式(1)中,R(j)称为局部自相关函数。从巴克码计算的局部自相关函数可以看到,它满足作为群同步码字的第一条特性,也就是说巴克码的局部自相关函数具有尖锐单峰特性,从后面的分析同样可以看出,它的识别器结构非常简单。目前人们已找到了多个巴克码字,具体情况如表1所示。表中+表示+1,–表示–1。
    以n = 7的巴克码为例,它的局部自相关函数计算结果如下

    同样可以求出j = 3、4、5、6、7,以及j = -1、-2、-3、-4、-5、-6、-7时R(j)的值为

    根据式(2)计算出来的这些值,可以作出7位巴克码关于R(j)与j的关系曲线,如图2。由图2可以看出,自相关函数在j=0时具有尖锐的单峰特性。局部自相关函数具有尖锐的单峰特性正是连贯式插入群同步码字的主要要求之一。

    2.巴克码识别器
    巴克码识别器是比较容易实现的,这里以七位巴克码为例,用7级移位寄存器、相加器和判决器就可以组成一识别器,具体结构如图7-16所示。7级移位寄存器的1、0端输出按照1110010的顺序连接到相加器输入,接法与巴克码的规律一致。当输入数据的“1”存入移位寄存器时,“1”端的输出电平为+1,而“0”端的输出电平为-1;反之,存入数据“0”时,“0”端的输出电平为+1,“1”端的电平为-1。
    当发送端送来的码元自右向左进入时,首先考虑一个简单的情况:假设只计算巴克码(1110010)进入的几个移位寄存器的输出,此时将有巴克码进入一位,二位……七位全部进入,第一位移出尚留六位……前六位移出只留一位等13种情况。经过计算可得相加器的输出就是自相关函数,设码元进入移位寄存器数目为a,码元尚留在移位寄存器的数目是b,这是就可以得到a、b和j之间的关系式

    根据上述关系可以得到表2,它反映了相加器输出与a、b之间的关系。

    实际上述群同步码的前后都是有信息码的,具体情况如图4(a)所示,在这种情况下巴克码识别器的输出波形如图4(b)所示。

    当七位巴克码在图4中的t1时刻,正好已全部进入了7级移位寄存器,这时7个移位寄存器输出端都输出+1,相加后得最大输出+7,如图4(b)所示,而判决器输出的两个脉冲之间的数据,称为一群数据或称为一帧数据。
    当然,对于信息而言,由于其具有的随机特性,可以考察一种最不利的情况:即当巴克码只有部分码在移位寄存器时,信息码占有的其它移位寄存器的输出全部是+1,在这样一种对于群同步最不利的情况下,相加器的输出将如表3所示。由此可得到相加器的输出波形如图5所示。图中横坐标用a表示,由a、b和j之间的关系可知,a=14-b。

    由图5可以看出,如果判决电平选择为6,就可以根据a=7时相加器输出的7,大于判决电平6而判定巴克码全部进入移位寄存器的位置。此时识别器输出一个群同步脉冲,表示群的开头。一般情况下,信息码不会正好都使移位寄存器的输出均为+1,因此实际上更容易判定巴克码全部进入移位寄存器的位置。后面还要讲到如果巴克码中有误码时,只要错一个码,当a=7时相加器输出将由7变为5,低于判决器的判决电平。因此,为了提高群同步的抗干扰性能,防止漏同步,判决电平可以改为4。但改为4以后容易发生假同步,这些问题在性能分析时要进一步讨论。
    间歇式插入法
    在某些情况下,群同步码字不再是集中插入在信息码流中,而是将它分散地插入,即每隔一定数量的信息码元,插入一个群同步码字。这种群同步码字的插入方式被称为间歇式插入法。
    当然集中式插入法和间歇式插入法在实际系统当中都有应用,例如在32路数字电话PCM系统中,实际上只有30路通电话,另外两路中的一路专门作为群同步码传输,而另一路作为其它标志信号用,这就是连贯式插入法的一个应用实例。而在24路PCM系统中,群同步则采用间歇式插入法。在这个系统中,一个抽样值用8位码表示,此时24路电话都抽样一次共有24个抽样值,192(24×8=192)个信息码元。192个信息码元作为一帧,在这一帧插入一个群同步码元,这样一帧共193个码元。24路PCM系统如图7-19所示:
    由于间歇式插入法,是将群同步码元分散的插入倒信息流中,因此,群同步码码型选择有一定的要求,其主要原则是:首先要便于收端识别,即要求群同步码具有特定的规律性,这种码型可以是全“1”码、“1”“0”交替码等;其次,要使群同步码的码型尽量和信息码相区别。例如在某些PCM多路数字电话系统中,用全“0”码代表“振铃”,用全“1”码代表“不振铃”,这时,为了使群同步码字与振铃相区别,群同步码就不能使用全“1”或全“0”。
    收端要确定群同步码的位置,就必须对接收的码进行搜索检测。一种常用检测方法为逐码移位法,它是一种串行的检测方法;另一种方法是RAM帧码检测法,它是利用RAM构成帧码提取电路的一种并行检测方法。这里将介绍逐码移位法的基本原理和实现同步的过程。

    逐码移位法的基本原理就是,由位同步脉冲(位同步码)经过n次分频以后的本地群码(频率是正确的,但相位不确定)与接收到码元中间歇式插入的群同步码进行远码移位比较,使本地群码与发送来的群同步码同步。其原理结构框图如图7:

    图7中异或门、延迟一位电路和禁门是专门用来扣除位同步码元以调整本地群码相位的,具体过程可以通过图8看到。
    设接收信码(波形c)中的群同步码位于画斜线码元的位置,后面依次安排各路信息码1、2、3(为简单起见,只包含三路信息码)。如果系统已经实现了群同步,则位同步码(波形a)经四次分频后,就可以使得本地群码的相位与收信码中的群同步码的相位一致。现在假设开始时如波形d图所示,本地群码的位置与波形c收信码中的群码位置相差两个码元位。为了易于看出逐码移位法的工作过程,假设群码为全“1”码,其余的信息码均与群码不同,为“0”。在第一码元时间,波形c与d不一致,原理图中的异或门有输出(波形e),经延迟一码元后,得波形f加于禁门,扣掉位同步码的第2个码元(波形b的第2个码元位置用加一叉号表示),这样分频器的状态在第2码元期间没有变化,因而分频器本地群码的输出仍保持和第1码元时相同。这时,它的位置只与收信码中的群码位置相差一位了(见波形d1)。

    类似地在第2码元时间,c又和d1进行比较,产生码形e1和f1,又在第3码元位置上扣掉一个位同步码,使本地群码的位置又往后移一位(波形d2)。至此以后,收信码中的群码与本地群码的位置就完全一致了,因而就实现了群同步。同时,也就提供了各路的定时信号。
    从图8表示的群同步建立原理来看,如果信息码中所有的码都与群码不同,那么最多只要连续经过N次调整,经过NTb的时间就可以建立同步了。但实际上信息码中“l”、“0”码均会出现,当出现“1”码时,在上面群同步过程的例子中,第1个位同步码对应的时间内信息码为“1”,图7-21中异或门输出 e=0,f=0禁门不起作用,不扣除第2位同步码,因此本地群码不会向右移展宽,这一帧调整不起作用,一直要到下一帧才有可能调整。假如下一帧本地群码d还是与信码中“1”码相对应,则调整又不起作用。当信息码中1、0码等概出现时,即P(1)=P(0)=0.5时,经过计算,群同步平均建立的时间近似为 (5)
    群同步系统的性能指标
    对于群同步系统而言,希望其建立的时间要短、建立同步以后应该具有较强的抗干扰能力。因此,在通常情况下,用以下三个性能指标来表示群同步性能的好坏,它们是:(1)漏同步概率P1;(2)假同步概率P2;(3)群同步平均建立时间ts。
    不同形式的同步系统,性能自然也不同。在此将主要分析集中插入方式的群同步系统的性能。
    1.漏同步概率P1
    由于噪声和干扰的影响,会引起群同步码字中一些码元发生错误,从而使识别器漏识别已发出的群同步码字,出现这种情况的概率称为漏识概率,用符号 来表示。以7位巴克码识别器为例,设判决门限为6,此时7位巴克码中只要有一位码发生错误,当7位巴克码全部进入识别器时,相加器输出就由7变5,小于判决门限6,这时就出现了漏同步情况,因此,只有一位码也不错才不会发生漏同步。若在这种情况下,将判决门限电平降为4,识别器就不会漏识别,这时判决器容许7位同步码字中有一个错误码元。
    在信息码中也可能出现与所要识别的群同步码字相同的码字,这时识别器会把它误认为群同步码字而出现假同步。出现这种情况的概率就被称为假同步概率,用符号P2表示。
    因此,计算假同步概率P2计算信息码元中能被判为同步码字的组合数与所有可能的码字数之比。设二进制信息码中1和0码等概出现,也就是P(1)=P(0)=0.5,则由该二进制码元组成n位码字的所有可能的码字数为2n个,而其中能被判为同步码字的组合数也与m有关,这里m表示判决器容许群同步码字中最大错码数,若m=0时,只有 个码字能识别;若M=1,则有 个码字能识别。以此类推,就可求出信息码元中可以被判为同步码字的组合数,这个数可以表示为 ,由此可得假同步概率的表达式为

    从式(6)和式(7)可以看到,随着m的增大,也就是随着判决门限电平降低,P1减小,但P2将增大,所以这两项指标是相互矛盾的。所以,判决门限的选取要兼顾漏同步概率和假同步概率。
    3.群同步平均建立时间ts
    对于连贯式插入的群同步而言,设漏同步和假同步都不发生,也就是P1 = 0和P2 = 0。在最不利的情况下,实现群同步最多需要一群的时间。设每群的码元数为N(其中m位为群同步码),每码元时间为Tb,则一群码的时间为NTb。考虑到出现一次漏同步或一次假同步大致要多花费 的时间才能建立起群同步,故群同步的平均建立时间大致为:

    群同步的保护
    1.连贯式插入法中的群同步保护
    连贯式插入法中的群同步保护电路如图9。在群同步尚末建立时,系统处于捕捉态,状态触发器C的Q端为低电平,群同步码字识别器的判决门限电平较高,因而就减小了假同步概率P2。这时在保护电路中,由于把判决门限电平调高,假同步的概率已很小,故保护电路中的n分频器被置零,禁止位同步n分频后输出。这里的n表示一帧数据的长度,因此,在置零信号无效时,位同步n分频后可以输出一个与群同步同频的信号,但脉冲位置不能保证与群同步脉冲位置相同,而这个脉冲位置也正是需要捕捉态确定的。

    从图9可以看到,为了减小假同步的概率,必须连续 次接收的码元与本地群码相一致,才被认为是建立了同步,采用这种方法可使假同步的概率大大减小。
    状态触发器C在同步末建立时处于“捕捉态”(此时Q端为低电平)。本地群码和收码只有连续n1次一致时,n1计数电路才输出一个脉冲使状态触发器的Q端由低电平变为高电平,群同步系统就由捕捉态转为维持态,表示同步已经建立。这样收码就可通过与门1加至解调器。偶然的一致是不会使状态触发器改变状态的,因为 次中只要有一次不一致,就会使计数电路置“0”。
    同步建立以后,可以利用状态触发器C和n2计数电路,来防止漏同步以提高同步系统的抗干扰能力。一旦转为维持状态以后,触发器C的Q反端变为低电乎,将与门2封闭。这时即使由于某些干扰使e有输出,也不会调整本地群码的相位。如果是真正的失步,e就会不断地将输出加到n2计数电路,同时e的反也不断将 计数电路置“0”。这时n1计数电路也不会再有输出加到n2计数电路的置“0”端上,而当n2计数电路输入脉冲的累计数达到n2时,就输出一个脉冲使状态触发器由维持态转为捕捉态,C触发器的Q反端转为高电平。这样,一方面与门2打开,群同步系统又重新进行逐码移位,另一方面封闭与门1,使解调器暂停工作。由此可以看出,将逐码移位法群同步系统划分为捕捉态和维持态后,既提高了同步系统的可靠性,又增加了系统的抗干扰能力。

    展开全文
  • 帧同步

    千次阅读 2019-05-07 11:49:29
    帧同步技术是早期RTS游戏常用的一种同步技术,本篇文章要给大家介绍的是RTX游戏中帧同步实现,帧同步是一种前后端数据同步的方式,一般应用于对实时性要求很高的网络游戏,想要了解更多帧同步的知识,继续往下看。

    帧同步技术是早期RTS游戏常用的一种同步技术,本篇文章要给大家介绍的是RTX游戏中帧同步实现,帧同步是一种前后端数据同步的方式,一般应用于对实时性要求很高的网络游戏,想要了解更多帧同步的知识,继续往下看。

    一.背景

    帧同步技术是早期RTS游戏常用的一种同步技术。与状态同步不同的是,帧同步只同步操作,其大部分游戏逻辑都在客户端上实现,服务器主要负责广播和验证操作,有着逻辑直观易实现、数据量少、可重播等优点。

    部分PC游戏如帝国时代、魔兽争霸3、星际争霸等,Host(服务器或某客户端)只当接收到所有客户端在某帧输入数据后,才会继续执行,等待直至超时认为该客户端掉线。很明显,当部分客户端因网络或设备问题无法及时上传操作数据,会影响其它客户端的表现,造成不好的游戏体验。考虑到游戏公平竞争性,这种需要等待的机制是必需的,但并不符合手游网络环境的需求。为此,需要使用“乐观”模式,即是Host采集客户端上传操作并按固定频率广播已接收到的操作数据,不在乎部分客户端的操作数据是否上传成功,且不会影响到其它客户端的游戏表现,如图1所示。

    二.剖析Unity3D

    帧同步技术最基础的核心概念就是相同输入,经过相同计算过程,得出相同计算结果。按照该概念,下面将简单描述Unity3D实现帧同步时所需要改造的一些方面,Unity3D中脚本生命周期流程图如图2所示。

    帧同步需要避免使用本地计时器相关数值。因此,使用Unity3D实现帧同步的过程所需注意的几点:

    1. 禁用Time类相关属性及函数,如Time.deltaTime等。而使用帧时间(第N帧 X 固定频率)

    2. 禁用Invoke()等函数

    3. 避免在Awake()、Start()、Update()、LateUpdate()、OnDestroy()等函数中实现影响游戏逻辑判断的代码

    4. 避免使用Unity3D自带物理引擎

    5. 避免使用协程Coroutine

    三.具体实现

    对于本文的实现,有如下定义:

    关键帧:服务器按固定频率广播的操作数据帧,使用唯一ID标识,主要包括客户端输入数据或服务器发送的关键信息(例如游戏开始或结束等消息)

    填充帧:由于设备性能和网络延迟等原因,服务器广播频率不可能达到客户端的更新频率。若只使用关键帧来驱动游戏运作,就会造成游戏卡顿,影响体验。因此,除关键帧外,客户端需要自行添加若干空数据帧,以使游戏表现更为流畅

    逻辑帧更新时间:客户端执行一帧所需时间,可根据设备性能和网络环境等因素动态变化

    服务器帧更新时间:服务器广播帧数据的固定频率,一般用于帧间隔时间差的逻辑计算

    3.1 主循环

    帧同步要求相同的计算过程,这就涉及到两个方面,其一是顺序一致,Unity3D主循环不可控,需自定义游戏循环,统一管理游戏对象以及脚本的执行,确保所有对象更新与逻辑执行顺序完全一致。另一方面是结果一致,凡有浮点数参与的逻辑计算需要特殊处理。
    class MainLoopManager : MonoBehaviour
    {
    bool m_start;
    int m_logicFrameDelta;//逻辑帧更新时间
    int m_logicFrameAdd;//累积时间

    void Loop()
    {
        ......//遍历所有脚本
    }
    
    void Update()
    {
        if (!m_start)
            return;
    
        if (m_logicFrameAdd < m_logicFrameDelta)
        {
            m_logicFrameAdd += (int)(Time.deltaTime * 1000);
        }
        else
        {
            int frameNum = 0;
            while(CanUpdateNextFrame() || IsFillFrame())
            {
                Loop();//主循环
                frameNum++;
                if (frameNum > 10)
                {
                    //最多连续播放10帧
                    break;
                }
            }
            m_logicFrameAdd = 0;
        }
    }
    
    bool CanUpdateNextFrame();//是否可以更新至下一关键帧
    bool IsFillFrame();//当前逻辑帧是否为填充帧
    

    }
    复制代码

    3.2 自定义MonoBehaviour

    Unity3D脚本生命周期中部分函数、Invoke、Coroutine调用时机与本地更新相关,并不满足帧同步机制的要求。我们通过继承MonoBehaviour类来实现上述函数和功能需求,并使所有涉及逻辑计算的组件都继承该自定义类。

    class CustomBehaviour : MonoBehaviour
    {
    bool m_isDestroy = false;

    public bool IsDestroy
    {
        get { returnm_isDestroy; }
    }
    
    public virtual void OnDestroy() {};
     
    public void Destroy(UnityEngine.Objectobj)
    {
    
        ......//销毁游戏对象
    
    }
    

    }

    3.2.1 Update()与LateUpdate()

    从可控性和高效性两方面来看,不建议采用逐一遍历游戏对象获取CustomBehaviour的方式去调用Update()与LateUpdate(),而是单独使用列表来管理。

    delegate void FrameUpdateFunc();
    class FrameUpdate
    {
    public FrameUpdateFunc func;
    public GameObject ower;
    public CustomBehaviour behaviour;
    }

    class MainLoopManager : MonoBehaviour
    {

    List m_frameUpdateList;
    List m_frameLateUpdateList;

    public RegisterFrameUpdate(FrameUpdateFunc func, GameObject owner)
    public UnRegisterFrameUpdate(FrameUpdateFunc func, GameObject owner)
    public RegisterFrameLateUpdate(FrameUpdateFunc func, GameObject owner)
    public UnRegisterFrameLateUpdate(FrameUpdateFunc func, GameObject owner)
    

    void Loop()
    {
    //先遍历m_frameUpdateList
    //再遍历m_frameLateUpdateList
    }

    }

    采取添加删除的方式,对组件是否需要执行Update()与LateUpdate()进行动态地管理,除了具有相对的灵活性,也保证了执行效率。

    3.2.2 Invoke相关函数

    Invoke、 InvokeRepeating、 CancelInvoke等函数需要使用C#中的反射机制,根据object对象obj和函数名methodName来获取MethodInfo如:

    var type = obj.GetType();
    MethodInfo method = type.GetMethod(methodName);

    通过接口封装,组成相关数据(InvokeData),放入列表等待执行。

    class InvokeData
    {
    public object obj;
    public MethodInfo methodInfo;
    public int delayTime;
    public int repeatRate;
    public int repeatFrameAt;
    public bool isCancel = false;
    }

    如上述结构,delayTime用于记录延迟执行时间,repeatRate代表重复调用的频率,repeatFrameAt则标记上次调用发生的帧序号,而isCancel标记Invoke是否被取消。最后,统一使用MethodBase.Invoke(objectobj, object[] parameters)执行调用。

    class MainLoopManager : MonoBehaviour
    {

    List m_invokeList;

    void Loop()
    {
        //先遍历m_frameUpdateList
        //再遍历m_frameLateUpdateList
        //遍历m_invokeList,并根据相关属性分别进行Invoke、 InvokeRepeating、CancelInvoke
    }
    ......
    

    }

    3.2.3 协程Coroutine

    协程Coroutine较复杂,必需采用的情况较少,本文方案未实现协程Coroutine功能,而是避免使用。

    3.2.4 Destroy相关

    在Destroy游戏对象或组件后,OnDestroy()将在下一帧执行。因此,需要采取可控的方式代替OnDestroy()函数完成资源的释放。

       class CustomBehaviour : MonoBehaviour
        {
            bool m_isDestroy = false;
            public bool IsDestroy
            {
                set { m_isDestroy = value; }
                get { return m_isDestroy; }
            }
            public virtual void DoDestroy() {};
            public void Destroy(UnityEngine.Object obj)
            {
                if (obj.GetType() == typeof(GameObject))
                {
                    GameObject go = (GameObject)obj;
                    CustomBehaviour behaviours = go.GetComponents();
                    for (int i = 0; i < behaviours.Length; i++)
                    {
                        behaviours[i].IsDestroy = true;
                        behaviours[i].DoDestroy();
                    }
                }
                else if (obj.GetType() == typeof(CustomBehaviour))
                {
                    CustomBehaviour behaviour = (CustomBehaviour)obj;
                    behaviour.IsDestroy = true;
                    behaviour.DoDestroy();
                }
                UnityEngine.Object.Destroy(obj);
            }
        }
    

    3.3 Time类与随机数

    帧同步游戏逻辑所有涉及时间的计算都应采用帧时间,即:当前帧序列数 * 服务器帧更新时间 /(填充帧数 + 1),而每帧随机数计算都由服务器下发种子来控制。如下:

    class MainLoopManager : MonoBehaviour
    {

    int m_serverFrameDelta;//毫秒
    int m_curFrameIndex;
    int m_fillFrameNum;
    int m_serverRandomSeed;

    public int serverRandomSeed
    {
        get { return m_serverRandomSeed; }
    }
    public int curFrameIndex
    {
        get { return m_curFrameIndex; }
    }
    public static int curFrameTime
    {
        return m_curFrameIndex * m_serverFrameDelta / (1 + m_fillFrameNum);
    }
    public static int deltaFrameTime
    {
        return m_serverFrameDelta / (1 + m_fillFrameNum);
    }
    .......
    

    }

    可写入CustomBehaviour中,便于自定义Time类的调用,避免误用Unity3D的Time类,Random类同理。

    class CustomBehaviour : MonoBehaviour
    {
    protected class Time
    {
    public static Fix time
    {
    get { return (Fix)MainLoopManager.curFrameTime / 1000; }
    }

        public static Fix deltaTime
        {
            get { return (Fix)MainLoopManager.deltaFrameTime / 1000; }
        }
    }
    
    protected class Random
    {
        public static Fix Range(Fix min, Fix max)
        {
            Fix diff = max - min;
            Fix seed = MainLoopManager.serverRandomSeed;
            return min + (int)FixMath.Round(diff * (seed / 100));
        }
    }
    

    }

    其中Fix是定点数,3.4小节会简单描述如何将定点数运用在Unity3D中。本文实现中约定随机种子范围在0-100之间,并采用简单的计算方式。如有特殊需求,自行实现。

    3.4 定点数

    比较简单的方式是,在原来浮点数的基础上乘1000或10000,对应地方除以1000或10000
    其中FP,就可以完全代替Float,我们只需要将我们自己的逻辑部分,Float等改造为FP,TSVector对应Vector3
    Photon网络的早期版本,Truesync

    客户端必须保证对网络帧操作的运算过程和结果一致,然而不同系统平台对浮点数的处理有差别,即便差别甚微,也会造成“蝴蝶效应”,导致不同步现象出现。绝大多数情况下,只需要对游戏对象方位进行定点数改造即可。而Unity3D并非开源游戏引擎,无法对底层transform的position和rotation进行修改。因此,逻辑层计算时需要使用到自定义以定点数为基础的position和rotation,并在每次循环结束之前,将自定义的方位逻辑计算之后所得信息转化Unity3D transform,以便Unity3D更新表现层。使用Unity3D的协同功能Coroutine以及WaitForEndOfFrame()可满足上述需求,即在逻辑层计算完成后,在Unity3D渲染之前更新底层transform的position和rotation。

    3.5 网络波动

    帧同步机制下,玩家输入发送到网络,所有响应都必须要等网络逻辑帧才能进行处理。理想环境下,网络帧操作接收到的频率是固定的,能保证客户端表现正常不卡顿。但事实是,绝大多数情况下网络都是不稳定的,时快时慢难以预测。最简单的方案就是建立一个网络逻辑帧的缓冲区,设置一个缓冲区上限,当存入缓存区的帧数满足上限之后,按照固定频率播放。若缓冲区变空,等待其重新填满。通过累积网络逻辑帧延迟,平均分布到固定频率,平滑处理了网络波动造成的卡顿。

    3.6 丢帧处理

    由于TCP的丢包重传机制会导致较大的延迟,大多数情况下,帧同步都采用UDP协议进行网络通信,这就意味着需要自行解决丢包问题。

    预防:关键帧数据包里携带前面两帧的数据,可大大降低丢包率,但会带来冗余的增加。因此,值得注意的是不能使用UDP数据包过大,否则部分路由器会在组合UPD分组时发生错误,建议不超过Internet标准MTU尺寸576byte。

    补救:虽然上述方案能起到预防丢帧的作用,仍然无法避免丢帧问题。在出现丢帧问题时,需要客户端根据所需帧序号主动向服务器请求关键帧,包括单帧请求和批量帧请求。为了保证能够获取到所需关键帧,建议采用TCP协议。

    四.结束语

    上述内容都是基于《全民XXX》帧同步机制,是对实现过程中所面临难题的总结。在此分享,希望对他人有所帮助。由于作者技术和写作水平有限,若有更好的意见或错误的地方,欢迎指导。

    http://www.360doc.com/content/17/0424/15/6432946_648246185.shtml
    https://blog.csdn.net/UWA4D/article/details/81486242
    http://www.sohu.com/a/153269736_163917

    展开全文
  • 帧同步和状态同步

    2017-11-07 12:05:04
    帧同步和状态同步去英雄互娱面试突然说到了对游戏中的网络实现问题,面试官告诉我两个名词:帧同步和状态同步 ...同步信号可以是每帧的像素数据,也可以是影响数据变化的关键事件信息。帧同步常被RTS(即时战略

    帧同步和状态同步

    去英雄互娱面试突然说到了对游戏中的网络实现问题,面试官告诉我两个名词:帧同步和状态同步
    小白并不懂所以开贴记录下来


    帧同步:

    帧同步,根据wiki百科的定义是,一种对同步源进行像素级同步显示的处理技术,对于网络上的多个接入者,一个信号将会通过主机同步发送给其他人,并同步显示在各个终端上。同步信号可以是每帧的像素数据,也可以是影响数据变化的关键事件信息。

    帧同步常被RTS(即时战略)游戏常采用。在游戏中同步的是玩家的操作指令,操作指令包含当前的帧索引。一般的流程是客户端上传操作到服务器, 服务器收到后并不计算游戏行为, 而是转发到所有客户端。这里最重要的概念就是 相同的输入 + 相同的时机 = 相同的输出。

    状态同步

    状态同步:同步的是游戏中的各种状态。一般的流程是客户端上传操作到服务器,服务器收到后计算游戏行为的结果,然后以广播的方式下发游戏中各种状态,客户端收到状态后再根据状态显示内容。状态同步最广泛的应用应该是在回合制游戏中。

    状态同步其实是一种不严谨的同步。它的思想中,不同玩家屏幕上的表现的一致性并不是重要指标, 只要每次操作的结果相同即可。所以状态同步对网络延迟的要求并不高。像玩RPG游戏,200-300ms的延迟也可以接受。 但是在RTS游戏中,50ms的延迟也会很受伤。

    自我理解

    面试官问我魔兽世界和魔兽争霸的不同,通过上述的描述就可以比较清楚的知道:

    针对魔兽争霸来说用的是帧同步,首先因为魔兽来说单位特别多,全部都占用服务器资源会很伤,只是广播玩家的操作,不需要计算,对于实时性也会很好,计算需求都在客户端使用。这也体现了我在玩赤潮下的一个问题,赤潮万到后期6个人超多个单位,所有计算都在手机上,渲染什么的都非常卡,特别影响体验,技能也丢不出去,这也是我后来不玩赤潮的主要原因之一。在想后期出安卓版的赤潮,有多少手机带不动。

    针对魔兽世界来说用的是状态同步,实时性不是很好,并且占用服务器的资源,但是对于玩家来说屏幕的一致性并不是重要指标,我的每次操作都可以得到正确的结果,对游戏的体验性会好很多。但是在网络环境较差的情况下,使用状态同步,会造成我明明向前走了很多步,突然就会回退到前面的位置,服务器因为网络延迟没有收到你中间的一系列的操作指令。

    参考1 http://blog.csdn.net/david_dai_1108/article/details/73437736
    参考2 http://blog.sina.com.cn/s/blog_674f1bd20101omv7.html

    展开全文
  • 基于FPGA的帧同步设计

    千次阅读 2019-07-21 10:01:02
    在数字时分多路通信系统中,为了能正确分离各路时隙信号,在发送端必须提供每帧的起始标记,在接收端检测并获取这一标志的过程称为帧同步帧同步有起止式同步法和插入特殊同步码组法两种。要求开机后整个系统要能...

    一、题目背景

    在数字时分多路通信系统中,为了能正确分离各路时隙信号,在发送端必须提供每帧的起始标记,在接收端检测并获取这一标志的过程称为帧同步。

    帧同步有起止式同步法和插入特殊同步码组法两种。要求开机后整个系统要能很快地进人帧同步,或一旦帧失步后,能很快恢复帧同步。帧失步将使信息丢失,对于语音通信来讲,人耳不易察觉出小于100 ms的通信中断,所以一般认为帧同步恢复时间在几十毫秒量级是允许的。本次实验将对于PRBS15的特定码流检测,并采用32767个比特作为帧长。最后用PRBS7来模拟实际中传输误码的情况。

    二、任务要求

    串行比特流信号输入后,输出帧同步信号,同时输出指示信号。当找到帧同步头,输出同步后数据,指示灯亮;否则,输出数据为 0,指示灯灭。当输入使能信号 为高电平时,信号输入帧同步模块,完成帧同步检测后,当找不到帧同步头,输出数据为 0,指示灯灭;当找到帧同步头,输出同步后数据,out_frame_en 输出为 1,指示灯亮。

    三、所需设备和软件

    FPGA AX309开发板、PC机、ISE、Modelsim、VHDL/Verilog、示波器。

    四、设计思路

    首先利用伪随机序列原理产生两组数据(根据帧格式设定长度),一组包含帧同步头(这里采用PRBS15作为信源 1),另一组为随机数(这里采用PRBS7作为干扰信号信源 2)。在拨码开关作用下分别选择信源 1 或信源 2 作为信号。帧同步模块对输入进来的信号进行相关运算,检测帧同步头的起始位置,完成帧同步检测后,如果找不到帧同步头,输出数据为 0指示灯灭;当找到帧同步头,输出同步后数据, 输出为1,指示灯亮。并通过Modelsim仿真,及下载到电路板上示波器观察波形。

    五、模块设计及相关代码

    1.PRBS15码型发成模块(同时包含BPRS7码型切换)

    基本原理:PRBS码即伪随机码,常用于高速串行通道的测试。其对于信道来说,码型看上去像是随机的,没有规律的出现,但实际上的码型是由生成多项式确定了的,并且有重复周期。下图为PRBS7码的线性反馈移位寄存器发生原理:

    PRBS15模块代码

    module PRBS15(
    	input clk,
    	input rst_n,
    	input key,
    	output reg out);         //最终输出
    reg tag;                       //状态标志位
    reg[15:1]PRBS15;      //15位寄存器作为PRBS 15码型发生器
    reg[7:1]PRBS7;       //7位寄存器作为PRBS 15码型发生器
    always@(negedge rst_n or negedge key)
    begin
    if(rst_n==0)
    	tag<=0;
    else
    	tag<=~tag;         //按键按下时标志位切换状态
    end		
    always@(posedge clk or negedge rst_n)
    begin
    if(rst_n==0)
    	begin
    	out<=0;
    	PRBS15<=1;
    	PRBS7<=1;
    	end
    else if(tag==0)
    	begin
    	PRBS15<={PRBS15[14:1],PRBS15[1]};     
    	PRBS15[1]<=(PRBS15[15]^PRBS15[14]);     //根据线性反馈移位寄存器,将输出码型送到out
    	out<=PRBS15[15];
    	end
    else if(tag)     //标志位为1代表按键按下,切换码型到out
    	begin
    	PRBS7<={PRBS7[6:1],PRBS7[1]};
    	PRBS7[1]<=(PRBS7[7]^PRBS7[6]);       //原理同PRBS15,
    	out<=PRBS7[7];
    	end
    end
    endmodule
    

    modelsim仿真如下

    PRBS15码在这里插入图片描述
    PRBS15和PRBS7切换在这里插入图片描述

    2.前导码检测

    基本原理:每一帧的前15位作为检测位,若符合要求,则为一次同步。前十五位为000000000000001,故采用状态机检测需要15个状态。这里采用三段式状态机。

    module stm1(
    	input din,clk,RST,
    	output reg tag1,
    	output reg dout);
    parameter s0=0,s1=1,s2=2,s3=3,s4=4,s5=5,s6=6,s7=7,s8=8,
              s9=9,s10=10,s11=11,s12=12,s13=13,s14=14,s15=15;//定义15个状态    
    	reg [3:0] pr_state,nx_state;                          
    	reg [15:1]cnt;
    always @(posedge clk or negedge RST)      //第一段状态完成状态转移
    begin
    if (RST==0)
            pr_state<=s0;
    else
    	pr_state<=nx_state;            
    
    end
    always @(posedge clk or negedge RST)  //第二段完整判断状态转移条件,描述状态规律
     begin                               
    if (RST==0)
    	pr_state=s0;
    else
    	pr_state=nx_state;
    end
    always @(*)
    begin        
    case(pr_state)
    	s0:if(!din)
    	  nx_state<=s1;
              else nx_state<=s0;
    	s1:if(!din)
              nx_state<=s2;
              else
              nx_state<=s0;
    	s2:if(!din)
              nx_state<=s3;
              else
              nx_state<=s0;
    	s3:if(!din)
              nx_state<=s4;
              else
              nx_state<=s0;
    	s4:if(!din)
              nx_state<=s5;
              else
              nx_state<=s0;
    	s5:if(!din)
              nx_state<=s6;
              else
              nx_state<=s0;
    	s6:if(!din)
              nx_state<=s7;
              else
              nx_state<=s0;
    	s7:if(!din)
              nx_state<=s8;
              else
              nx_state<=s0;
    	s8:if(!din)
              nx_state<=s9;
              else
              nx_state<=s0;
    	s9:if(!din)
              nx_state<=s10;
              else
              nx_state<=s0;
    	s10:if(!din)
              nx_state<=s11;
              else
              nx_state<=s0;
    	s11:if(!din)
              nx_state<=s12;
              else
              nx_state<=s0;
    	s12:if(!din)
              nx_state<=s13;
              else
              nx_state<=s0;
    	s13:if(!din)
              nx_state<=s14;
              else
              nx_state<=s0;
    	s14:if(din)
              nx_state<=s15;
              else
              nx_state<=s0;
    	s15:nx_state<=s0;
    endcase
    end
    always @(posedge clk or negedge RST) //第三个状态机输出:当达到第15个状态时,输出
    begin                      //一个同步信号
    if(RST==0)
    	out<=0;
    else
    	begin
    	if(nx_state==s15)
    		dout<=1;
            else
                    dout<=0;
            end
    always@(posedge clk or negedge RST )   //将同步信号优化,拉长保持当前帧状态,方便
    begin                             //后面同步状态检测   
    if(RST==0||dout==1)
    	begin
            cnt<=0;
            tag1<=1;
            end          
    else if(cnt==32700)         //通过计数器延长标志
            begin
            cnt<=0;
            tag1<=0;
            end  
    else 
    	cnt<=cnt+1;
    end
    endmodule
    

    modelsim仿真如下

    dout输出

    在这里插入图片描述

    tag输出

    在这里插入图片描述

    3.同步状态机

    基本原理:通过检测上一个模块传来的标志信号,检测是否连续三次有同步信号,若连续检测到三次则判定同步,若过程中出现一次误码,则进入失警状态,若下次仍能检测到同步信号,则回到同步状态,否则判定失帧。同样使用三段式。状态转移图如下:
    在这里插入图片描述

    module stm2(   
    	input clk,   
    	input rst_n,
            input clk15,
            input tag1,
            output reg led);
            //帧检测
            parameter s0=0,s1=1,s2=2,s3=3,s4=4;
            reg [2:0] pr_state,nx_state;                  //定义5个状态
    always @(posedge clk or negedge rst_n)        //第一段状态转移
    begin
    if(rst_n==0)
    	pr_state<=s0;
    else
    	pr_state<=nx_state;
    end          
    always @(negedge clk15 or negedge rst_n)  //第二段状态检测
    begin
    if (rst_n==0)
    	nx_state<=s0;
    else
    case(pr_state)
    	s0:if(tag1)
              nx_state<=s1;
              else
              nx_state<=s0;
    	s1:if(tag1)
              nx_state<=s2;
              else
              nx_state<=s0;
    	s2:if(tag1)
              nx_state<=s3;
              else
              nx_state<=s0;
    	s3:if(tag1)
              nx_state<=s3;
              else
              nx_state<=s4;
    	s4:if(tag1)
              nx_state<=s3;
              else
              nx_state<=s0;
    endcase
    end         
    always @(posedge clk or negedge rst_n)    //第三段状态输出
    begin
    if(rst_n==0)
    	led<=0;
    else
    	begin
    	if(nx_state==s3||nx_state==s4)
            	led<=1;
            else
                    led<=0;
            end
    endmodule
    

    modelsim仿真如下

    在这里插入图片描述

    4.分频时钟检查信号

    module f(
    	input        clk,
    	input        rst_n,
    	input        dout,   
    	output       reg clk15);	
    reg [15:0] cnt;
    always@(posedge clk or negedge rst_n )
    begin
    if(rst_n==0||dout==1)
    	begin
            cnt<=0;
            clk15<=1;
            end
    else if(cnt==16383)
            begin
            cnt<=0;
            clk15<=~clk15;
            end  
    else 
            cnt<=cnt+1;
    end
    endmodule
    

    5.引脚约束文件

    NET "clk" LOC = T8 | TNM_NET = sys_clk_pin;
    TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 50000 kHz;
    NET rst_n  LOC = L3 | IOSTANDARD ="LVCMOS33";
    ## reset pushbutton
    NET key    LOC = C3 | IOSTANDARD ="LVCMOS33"; ## KEY1
    ########LED Pin define###################
    NET led    LOC = P4 | IOSTANDARD ="LVCMOS33"; ## LED1
    NET out1   LOC = H15 | IOSTANDARD= "LVCMOS33"; ## LED1
    NET dout   LOC = C10 | IOSTANDARD= "LVCMOS33"; ## dout
    NET clk1   LOC = C15 | IOSTANDARD = "LVCMOS33"; ## clk
    

    6.测试文件

    module tb;
    // Inputs
    reg clk;
    reg rst_n;
    reg key;
    // Outputs
    wire led;
    // Instantiate the Unit Under Test (UUT)
    top uut (
    	.clk(clk), 
    	.rst_n(rst_n), 
    	.key(key), 
    	.led(led));		
    initial begin
    
    // Initialize Inputs
    clk = 0;
    rst_n = 0;
    key = 1;
    // Wait 100 ns for global reset to finish
    #100      rst_n=1;
    end
    always #10 clk=~clk;
    always #3000000 key=~key;
    endmodule
    

    采用数字示波器显示最终结果

    在这里插入图片描述

    展开全文
  • 游戏后台状态同步与帧同步

    千次阅读 2017-11-11 23:19:12
    最近开始学习一下游戏后台的一些知识,一直很好奇多个玩家之间的数据是如何同步的,查了一下,目前使用的比较多的是状态同步和帧同步。状态同步同步的是游戏中的各种状态。一般的流程是客户端上传操作到服务器,...
  • 同步的概念 同步技术是数字通信系统中非常重要的技术。一般来说数字通信系统要实现多种同步功能才能实现正确的数据通信任务。其技术目标是实现不同地域收发双方的同步通信互联,实现一致的信息数据...发送信号和接受...
  • 一般 Android 系统相机的最高帧率在 30 FPS 左右,当帧率低于 20...我们在做相机预览和视频流处理时,对每帧图像处理时间过长(超过 30 ms)就很容易造成画面卡顿,这个场景就需要用到错帧同步方法去提升画面的流畅度。
  • LTE-同步信号

    千次阅读 2015-05-08 20:31:49
    2)辅同步信号:用于小区组侦测,timing对准,CP长度侦测 共有504个唯一的小区标识,物理层小区标志分成168个唯一的物理层小区标识组,每一个小组 包含3个唯一标识。这个分组中每一个物理小区标识是该分组的一...
  • 帧同步--竞技类网络游戏设计方案

    千次阅读 2017-05-23 18:41:26
    同步信号可以是每帧的像素数据,也可以是影响数据变化的关键事件信息。 帧同步在网络游戏中的应用,设计上有异于传统的mmorpg游戏,因为可以承载更大量的后台计算,实现类单机的效果,所以可应用在类似射击
  • 一个10ms 被分为两个5ms 半,每个半由4 个数据子和1 个特殊子构成。每个子分为两个0.5ms时隙,每个时隙又可分为7 个OFDM 符号。特殊子则由总时长为1ms 的三个特殊时隙组成:下行导频时隙...
  • 游戏帧同步的流程与实现

    千次阅读 2019-02-21 00:40:37
    帧同步的基本原理 帧事件数据采集 帧同步的事件处理与动画 帧同步的逻辑数据同步 帧同步之跳帧处理 现代多人游戏中,多个客户端之间的通讯大多以同步多方状态为主要目标,为了实现这一目标,主要有两个技术方向: ...
  • 同步信号PSS , SSS

    万次阅读 2017-08-30 09:36:08
    PSS SSS同步信号
  • 网络游戏之帧同步物理模拟

    千次阅读 2017-07-25 19:36:09
    笔者介绍:姜雪伟,IT公司技术合伙人,IT...CSDN视频网址:http://edu.csdn.net/lecturer/144 本篇博客我们将用网络中的帧同步技术进行物理模拟,帧同步是通过仅发送控制该系统的输入而不是该系统的状态将系统从一
  • 最近一个项目使用HI3516DV300平台,需要知道摄像头产生场同步(VSYNC同步信号)的具体时间,目前通过HI_MPI_VI_GetChnFrame可以获取每一的数据而且该数据结构中包含时间戳(VIDEO_FRAME_INFO_S.stVFrame.u64PTS...
  • Unity3D简单的帧同步方案

    千次阅读 2018-07-16 14:17:46
    百度了一下帧同步,百度百科上对帧同步的解释是:在数字时分多路通信系统中,为了能正确分离各路时隙信号,在发送端必须提供每帧的起始标记,在接收端检测并获取这一标志的过程称为帧同步。哈哈哈,一脸懵逼吧,...
  • 基于帧同步的游戏框架说明

    千次阅读 2019-05-09 14:08:28
    基于帧同步的游戏框架说明 一,关于帧同步和状态同步的比较 帧同步 状态同步 安全性 比较差,计算都在客户端,服务器只做转发;有服务器校验的方案,比较繁琐 ...
  • 利用zc序列进行简单的帧同步

    千次阅读 2019-11-01 22:14:32
    帧同步zc序列的产生同步算法 参考文章 https://wenku.baidu.com/view/accce6d1240c844769eaeea9.html zc序列的产生 产生zc序列,根据论文公式得出,K值可以用来评价ZC序列的好坏。1位最好,其次为signal_length-1. ...
  • 动作手游实时PVP帧同步方案

    千次阅读 2017-06-06 18:36:27
    动作手游实时PVP帧同步方案(客户端) 1、概述 1.1、基于UDP的帧同步方案  在技术选型方面,之所以选择帧同步方案,在Kevin的一篇介绍PVP帧同步后台实现的文章中已经做了详细叙述,这里简单摘要如下:  高一致...
  • 任何对帧同步有疑问的人,都应该来看这篇文章,这是参考了2个帧同步模型,遇到各种问题并一一解决之后,彻底明白帧同步讲的是什么玩意的一篇文章。断断续续修改了将近2个月,说多了都是泪:(。 言归简短,书归正传。...
  • 动作手游实时PVP帧同步方案(客户端) 1、概述 1.1、基于UDP的帧同步方案  在技术选型方面,之所以选择帧同步方案,在Kevin的一篇介绍PVP帧同步后台实现的文章中已经做了详细叙述,这里简单摘要如下: 高一致性...
  • LTE学习-PSS主同步信号

    千次阅读 2020-05-12 13:23:13
    PSS是一种特殊的物理层信号,用于无线帧同步。它的特性如下: 1.映射到72个有源子载波(6个RBs),在FDD模式下,处于slot 0 (Subframe 0)和slot 10 (Subframe 5)中,以直流子载波为中心。 2.在TDD模式下,处于slot 2 ...
  • 往往我们在处理图像数据的时候,图像数据在经过处理会耗费...per_frame_vsync_r : 预处理帧同步信号per_frame_href_r : 预处理行同步信号per_frame_clken_r : 预处理使能时钟信号read_frame_*** : shift_ram输出数...
  • 5G/NR同步信号之SSB概要

    千次阅读 2020-10-26 21:18:36
    同步信号和PBCH块(Synchronization Signal and PBCH block, 简称SSB),它由主同步信号(Primary Synchronization Signals, 简称PSS)、辅同步信号(Secondary Synchronization Signals, 简称SSS)、PBCH三部分共同组成。...
  • 第1章 同步信号块SSB概述 1.1 与同步信号块SSB相关的无线时频资源 1.2同步信号块SSB概述 1.3同步信号块SSB的来源和背景 1.4 理解本文的的所需要的前序知识 第2章 5G NR SSB内在的基本结构 2.1 SSB同步块的信道...
  • 异步同步通信数据格式

    千次阅读 2020-07-10 13:52:52
    串行通信可以分为两种类型:同步通信、异步通信. 1. 异步通信的特点及信息格式: 以起止式异步协议为例,下图显示的是起止式一数据的格式: 图1 起止式异步通信的特点是:一个字符一个字符地传输,每个字符一位一位...
  • 帧同步在竞技类网络游戏中的应用

    千次阅读 2015-08-04 10:01:16
    ...帧同步在网上可以搜的资料比较少,关于游戏的更是没有,不过,实现的原理也比较简单,最近几天就写了份关于帧同步的文档,当作给同事扫扫盲,顺便也在这里发发,可以给其他人参考参考  
  • TFT屏同步信号

    千次阅读 2016-07-07 10:58:10
    A:显示指针从矩形左上角的第一行第一个点开始,一个点一个点的在LCD上显示,在上面的时序图上用时间线表示就为VCLK,我们称之为像素时钟信号; B:当显示指针一直显示到矩形的右边就结束这一行,那么这一行的动作在...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 45,572
精华内容 18,228
关键字:

帧同步信号是什么