精华内容
下载资源
问答
  • 2020-03-18 10:10:40

    watch 让你能方便的观察到指定方法的调用情况。能观察到的范围为:返回值抛出异常入参,通过编写 OGNL 表达式进行对应变量的查看。

    参数说明

    watch 的参数比较多,主要是因为它能在 4 个不同的场景观察对象

    参数名称参数说明
    class-pattern类名表达式匹配
    method-pattern方法名表达式匹配
    express观察表达式
    condition-express条件表达式
    [b]方法调用之前观察
    [e]方法异常之后观察
    [s]方法返回之后观察
    [f]方法结束之后(正常返回和异常返回)观察
    [E]开启正则表达式匹配,默认为通配符匹配
    [x:]指定输出结果的属性遍历深度,默认为 1
    [n:]命令执行次数
    [#cost:]方法执行耗时

    这里重点要说明的是观察表达式,观察表达式的构成主要由 ognl 表达式组成,所以你可以这样写"{params,returnObj}",只要是一个合法的 ognl 表达式,都能被正常支持。

    观察的维度也比较多,主要体现在参数 advice  的数据结构上。Advice 参数最主要是封装了通知节点的所有信息。请参考表达式核心变量中关于该节点的描述。

    特别说明

    • watch 命令定义了4个观察事件点,即 -b 方法调用前,-e 方法异常后,-s 方法返回后,-f 方法结束后
    • 4个观察事件点 -b-e-s 默认关闭,-f 默认打开,当指定观察点被打开后,在相应事件点会对观察表达式进行求值并输出
    • 这里要注意方法入参方法出参的区别,有可能在中间被修改导致前后不一致,除了 -b 事件点 params 代表方法入参外,其余事件都代表方法出参
    • 当使用 -b 时,由于观察事件点是在方法调用前,此时返回值或异常均不存在

    同时观察方法调用前和方法返回后

    $ watch demo.MathGame primeFactors "{params,target,returnObj}"  "params[0] instanceof java.lang.Integer"  -x 2 -b -s -n 2
    Press Ctrl+C to abort.
    Affect(class-cnt:1 , method-cnt:1) cost in 46 ms.
    ts=2018-12-03 19:29:54; [cost=0.01696ms] result=@ArrayList[
        @Object[][
            @Integer[1544665400],
        ],
        @MathGame[
            random=@Random[java.util.Random@522b408a],
            illegalArgumentCount=@Integer[13038],
        ],
        null,
    ]
    ts=2018-12-03 19:29:54; [cost=4.277392ms] result=@ArrayList[
        @Object[][
            @Integer[1544665400],
        ],
        @MathGame[
            random=@Random[java.util.Random@522b408a],
            illegalArgumentCount=@Integer[13038],
        ],
        @ArrayList[
            @Integer[2],
            @Integer[2],
            @Integer[2],
            @Integer[5],
            @Integer[5],
            @Integer[73],
            @Integer[241],
            @Integer[439],
        ],
    ]
    
    • 参数里-n 2,表示只执行两次
    • 这里输出结果中,第一次输出的是方法调用前的观察表达式的结果,第二次输出的是方法返回后的表达式的结果
    • 结果的输出顺序和事件发生的先后顺序一致,和命令中 -s -b的顺序无关

    更多信息查看文档:https://alibaba.github.io/arthas/watch.html

    更多相关内容
  • 汶川大地震前后GPS观测的精密单历元解得到的震区地壳运动.pdf
  • 根据日环食射电联合观测研究的课题需要,用北京天文台高分辨率的太阳磁场望远镜,于1987年9月22、24日对太阳黑子的纵向磁场进行了观测,经过换算得到23日日食时有关黑子的磁场分布及其月掩情况。
  • 骨髓冻存前后CPU-GM集落生成观测.pdf
  • int flow2 = 6789; new Thread(new ...假设该方法为请求的处理方法 */ private static void runRequest(int flow){ //设置流水 setFlow(flow); //判断是否支持 https boolean supportHttps = condition1() &

    int flow2 = 6789;

    new Thread(new Runnable() {

    @Override

    public void run() {

    runRequest(flow2);

    }

    }).start();

    }

    }

    /**

    • 假设该方法为请求的处理方法

    */

    private static void runRequest(int flow){

    //设置流水

    setFlow(flow);

    //判断是否支持 https

    boolean supportHttps = condition1() && condition2() == 2 && “https”.equals(condition3());

    //获取前缀,getPrefix的参数是我们的观测目标,看它是true还是false

    String prefix = getPrefix(supportHttps);

    //输出前缀

    System.out.println(prefix);

    }

    private static String getPrefix(boolean supportHttps) {

    supportHttps = subCondition();

    return supportHttps ? “https” : “http”;

    }

    private static boolean condition1() {

    //复杂逻辑

    return true;

    }

    public static int condition2() {

    //复杂逻辑

    return 2;

    }

    public static String condition3() {

    //复杂逻辑

    return “https”;

    }

    private static boolean subCondition() {

    //复杂逻辑

    return false;

    }

    /**

    • 存储线程流水映射

    */

    private static final ConcurrentHashMap<Long,Integer> flowMap = new ConcurrentHashMap<>(10);

    /**

    • 根据当前线程id获取流水

    • @return flow 流水值

    */

    private static int getFlow(){

    return flowMap.getOrDefault(Thread.currentThread().getId(),0);

    }

    /**

    • 为当前线程id设置流水值

    • @param flow 流水值

    */

    private static void setFlow(int flow){

    flowMap.put(Thread.currentThread().getId(),flow);

    }

    }

    2.观测的目标


    getPrefix(boolean supportHttps) 方法被调用时,supportHttps 的值,到底是true还是false呢?

    二、观测&排查流程

    =======================================================================

    1.直接watch观测 getPrefix() 方法,拿到参数值


    如上图,我们拿到了 getPrefix() 方法的入参值supportHttps,是 false 来的!

    tips:通过静态方法拿到当前线程的flow并作为筛选条件 @com.company.TmpTest@getFlow()==1234 企业实践中,一般会将一些请求相关的信息放到可静态调用获取的地方,这就是筛选请求的重要利器

    2.业务及逻辑分析与观测结果不符


    boolean supportHttps = condition1() && condition2() == 2 && "https".equals(condition3()); 当我们从实际的业务和逻辑分析(代码没有呈现)看的时候,我们认为上面的表达值的值应该是 true 才对,为何观测到是false呢???是业务和逻辑分析错了吗?

    到底是哪里出了问题呢?为了找到答案,我们需要再进一步的分析!

    3.直接获取supportHttps变量的值?不可


    getPrefix()方法的入参值其实就是 supportHttps 变量,我们只要获取到该变量的值就能确定逻辑分析推断是否有问题了!

    但是,supportHttps 是方法内的临时变量,因此我们无法通过Arthas直接获取到它的值。

    相信对很多入门Arthas的人来说,都会这样的疑问:Arthas可以获取到方法内的临时变量吗?

    答案:可以,但又不完全可以!

    分析:既然不能直接观测,我们一般可以通过观测使用到该临时变量的方法来间接观测它的值,就像第1点做的那样,只是本次我们对这个值有所怀疑。另外,一般定义变量,都是为了接收方法的返回值,或者是作为方法的参数,因此,这部分的变量值还是有机会拿到滴!

    4.侧面求证,利用好短路机制


    boolean supportHttps = condition1() && condition2() == 2 && "https".equals(condition3()); 从上边的代码看,supportHttps 变量就是通过表达式求出来的,因此我们可以观测表达式的执行情况呀!

    分析:由于3个 condition方法 是通过 && 串起来的,又由于java中是有短路机制的,因此可以判定 condition1()==truecondition2()==true ,因为只有这样才会执行 condition3();

    5.condition3()返回了啥?是它导致了 supportHttps 为false吗?


    验证这个也非常简单,直接watch一下即可!

    可以看到,condition3() 的返回值是 https,由此 "https".equals("https") == true

    6.出现了!出现了!矛盾的 supportHttps


    通过上边的排查, 我们知道表达式 condition1() && condition2() == 2 && "https".equals(condition3())的值是true,那么 supportHttps 应该就是 true 才对啊!!为什么在 getPrefix() 方法的参数观测的时候,它是false来的呢???

    难道Arthas有什么隐藏的Bug?

    7.重新审视 watch 的使用


    我们都知道,watch是可以指定观测的时间点的,方法执行前和方法执行后的参数是有可能不一致的,但是这种不一致的情况一般是指对象类型中的内容被修改了。而我们观测 getPrefix() 方法时,虽然观测的是方法执行之后参数值,但是,按理说,getPrefix() 方法的入参是一个 boolean 类型啊,它不是对象类型,即使方法执行过程中有对参数进行重新赋值,但方法结束后它的值也不应该会变啊?

    private static String getPrefix(boolean supportHttps) {

    //改变了supportHttps的值

    supportHttps = subCondition();

    return supportHttps ? “https” : “http”;

    }

    8.没办法了,试一下吧,反正也没什么损失


    本来在排查过程中,女朋友也提出了会不会是因为在方法执行后观测,所以看到的结果为false,但是我第一反应就是这不可能,值传递和地址传递我可熟了,值传递在方法执行完之后怎么会变呢!!所以排查重点还是放在方法定位(多次调用和有重载)和condition的确认上,顺手还给她讲了一下地址传递的例子,对象啊,JsonObj啊啥的才会变。

    一直到最后(晚上12点多了),当时实在没有办法了,想着只能第二天开新实例开debug导流量了,最后抱着试一试的心态对watch加了-b参数,卧槽!!!还真是true,纳尼??卧槽?什么东西? [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iYH5Wjna-1635573783169)(https://upload-images.jianshu.io/upload_images/26809252-52289b89fa2d2266.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]

    三、引出问题

    ====================================================================

    问题:使用watch来观测方法参数(boolean类型),在方法中对该参数进行重新赋值的时候,执行前观测和执行后观测的参数结果不一致!

    四、求证

    ==================================================================

    1.毋庸置疑的值传递


    展开全文
  • 区域网GPS观测得到的汶川大地震前后的地壳垂直运动.pdf
  • 5·12汶川地震前后鲜水河断裂运动状况的变化——基于跨断裂连续GPS观测的认识.pdf
  • 汶川地震前后介质和应力应变演化过程——来自地震波速度、b值和GPS的观测结果.pdf
  • 期间也遇到了 Arthas中使用watch观测方法执行前后,基本类型参数的值不一致的问题。此问题的结论和原因虽然都比较简单,但其排查过程也可供学习记录。只想看结论的同学也可以直接看 第四点 !1.代码由于...

    一、背景

    某日晚,需要协助女朋友排查一个线上问题,其请求调用比较复杂,单次请求过来会多次通过不同路径调用存在问题的方法,并且还有很多重载的方法,排查过程中需要结合stack和各种条件判断,极其麻烦;期间也遇到了 Arthas中使用watch观测方法执行前后,基本类型参数的值不一致的问题。

    此问题的结论和原因虽然都比较简单,但其排查过程也可供学习记录。
    只想看结论的同学也可以直接看 第四点 !

    1.代码

    由于真实情况涉及公司业务,而且有很多无关紧要的逻辑,所以写了个超级简化版。

    package com.company;
    
    import java.util.concurrent.ConcurrentHashMap;
    
    public class TmpTest {
    
        public static void main(String[] args) throws InterruptedException {
            for (int i = 0; i < 1000; i++) {
                //睡眠10s,一是避免程序退出,二是可以持续观测
                Thread.sleep(10*1000);
    
                //这里使用了两个请求意在贴近实际场景,使用Arthas时,能够筛选出自己想要观测的请求是一个非常重要的能力
    
                //第一个请求进入,该请求是我们想要观测的请求,该flow1是固定或者可控的
                int flow1 = 1234;
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        runRequest(flow1);
                    }
                }).start();
                //第二个请求进入,该请求是其他用户发起的请求,是干扰项
                int flow2 = 6789;
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        runRequest(flow2);
                    }
                }).start();
    
            }
    
        }
    
        /**
         * 假设该方法为请求的处理方法
         */
        private static void runRequest(int flow){
            //设置流水
            setFlow(flow);
            //判断是否支持 https
            boolean supportHttps = condition1() && condition2() == 2 && "https".equals(condition3());
            //获取前缀,getPrefix的参数是我们的观测目标,看它是true还是false
            String prefix = getPrefix(supportHttps);
            //输出前缀
            System.out.println(prefix);
        }
    
        private static String getPrefix(boolean supportHttps) {
            supportHttps = subCondition();
            return supportHttps ? "https" : "http";
        }
    
        private static boolean condition1() {
            //复杂逻辑
            return true;
        }
    
        public static int condition2() {
            //复杂逻辑
            return 2;
        }
    
        public static String condition3() {
            //复杂逻辑
            return "https";
        }
    
        private static boolean subCondition() {
            //复杂逻辑
            return false;
        }
    
        /**
         * 存储线程流水映射
         */
        private static final ConcurrentHashMap<Long,Integer> flowMap = new ConcurrentHashMap<>(10);
    
        /**
         * 根据当前线程id获取流水
         * @return flow 流水值
         */
        private static int getFlow(){
            return flowMap.getOrDefault(Thread.currentThread().getId(),0);
        }
    
        /**
         * 为当前线程id设置流水值
         * @param flow 流水值
         */
        private static void setFlow(int flow){
            flowMap.put(Thread.currentThread().getId(),flow);
        }
    }
    

    2.观测的目标

    getPrefix(boolean supportHttps) 方法被调用时,supportHttps 的值,到底是true还是false呢?

    二、观测&排查流程

    1.直接watch观测 getPrefix() 方法,拿到参数值


    v2-d0269747f3445984f4cc2b3c976dcdf1_b.jpg


    如上图,我们拿到了 getPrefix() 方法的入参值supportHttps,是 false 来的!

    tips:通过静态方法拿到当前线程的flow并作为筛选条件 @com.company.TmpTest@getFlow()==1234 企业实践中,一般会将一些请求相关的信息放到可静态调用获取的地方,这就是筛选请求的重要利器

    2.业务及逻辑分析与观测结果不符

    boolean supportHttps = condition1() && condition2() == 2 && "https".equals(condition3()); 当我们从实际的业务和逻辑分析(代码没有呈现)看的时候,我们认为上面的表达值的值应该是 true 才对,为何观测到是false呢???是业务和逻辑分析错了吗?


    v2-567f2307a00df769d7e26c9e241657a5_b.jpg


    到底是哪里出了问题呢?为了找到答案,我们需要再进一步的分析!

    3.直接获取supportHttps变量的值?不可

    getPrefix()方法的入参值其实就是 supportHttps 变量,我们只要获取到该变量的值就能确定逻辑分析推断是否有问题了!
    但是,supportHttps 是方法内的临时变量,因此我们无法通过Arthas直接获取到它的值。

    相信对很多入门Arthas的人来说,都会这样的疑问:Arthas可以获取到方法内的临时变量吗?
    答案:可以,但又不完全可以!
    分析:既然不能直接观测,我们一般可以通过观测使用到该临时变量的方法来间接观测它的值,就像第1点做的那样,只是本次我们对这个值有所怀疑。另外,一般定义变量,都是为了接收方法的返回值,或者是作为方法的参数,因此,这部分的变量值还是有机会拿到滴!

    4.侧面求证,利用好短路机制

    boolean supportHttps = condition1() && condition2() == 2 && "https".equals(condition3()); 从上边的代码看,supportHttps 变量就是通过表达式求出来的,因此我们可以观测表达式的执行情况呀!


    v2-f984c460abab3040bb6953e90ab5945a_b.jpg


    分析:由于3个 condition方法 是通过 && 串起来的,又由于java中是有短路机制的,因此可以判定 condition1()==true 和 condition2()==true ,因为只有这样才会执行 condition3();

    5.condition3()返回了啥?是它导致了 supportHttps 为false吗?

    验证这个也非常简单,直接watch一下即可!


    v2-790437d42b70cad4352c9d3451417310_b.jpg


    可以看到,condition3() 的返回值是 https,由此 "https".equals("https") == true

    6.出现了!出现了!矛盾的 supportHttps

    通过上边的排查, 我们知道表达式 condition1() && condition2() == 2 && "https".equals(condition3())的值是true,那么 supportHttps 应该就是 true 才对啊!!为什么在 getPrefix() 方法的参数观测的时候,它是false来的呢???
    难道Arthas有什么隐藏的Bug?

    7.重新审视 watch 的使用

    我们都知道,watch是可以指定观测的时间点的,方法执行前和方法执行后的参数是有可能不一致的,但是这种不一致的情况一般是指对象类型中的内容被修改了。而我们观测 getPrefix() 方法时,虽然观测的是方法执行之后参数值,但是,按理说,getPrefix() 方法的入参是一个 boolean 类型啊,它不是对象类型,即使方法执行过程中有对参数进行重新赋值,但方法结束后它的值也不应该会变啊?

    private static String getPrefix(boolean supportHttps) {
        //改变了supportHttps的值
        supportHttps = subCondition();
        return supportHttps ? "https" : "http";
    }
    

    8.没办法了,试一下吧,反正也没什么损失

    本来在排查过程中,女朋友也提出了会不会是因为在方法执行后观测,所以看到的结果为false,但是我第一反应就是这不可能,值传递和地址传递我可熟了,值传递在方法执行完之后怎么会变呢!!所以排查重点还是放在方法定位(多次调用和有重载)和condition的确认上,顺手还给她讲了一下地址传递的例子,对象啊,JsonObj啊啥的才会变。

    一直到最后(晚上12点多了),当时实在没有办法了,想着只能第二天开新实例开debug导流量了,最后抱着试一试的心态对watch加了-b参数,卧槽!!!还真是true,纳尼??卧槽?什么东西?


    v2-3cb4e41357f6b92a73a9f330ac41014f_b.jpg


    三、引出问题

    问题:使用watch来观测方法参数(boolean类型),在方法中对该参数进行重新赋值的时候,执行前观测和执行后观测的参数结果不一致!

    四、求证

    1.毋庸置疑的值传递

    参数是 boolean 是值传递,这肯定是没错的。


    v2-b8c052c9276147cc3eb2e05879673fc3_b.jpg


    上图可见,执行完方法后,supportHttps的值是true。所以问题一定是出在Arthas观测的使用上。

    2.Arthas中watch命令的实现

    想要找到答案,那就必须了解arthas对watch命令的实现了,好在arthas提供了jad命令,并且允许逆编译增强过的类,让我们可以很方便地看到增强的情况。
    被观测的方法(getPrefix())逆编译结果:


    v2-a47c448d448642add2b64ad9a2a5e7bb_b.jpg


    方法被调用时外层方法(runRequest())逆编译结果:


    v2-bc28df7db5bc37a2ad5ba4672992a372_b.jpg


    3.恍然大明白

    方法结束之后 进行信息收集的两种做法:


    v2-15259dcba79fdd258b9cc356bda2f4f8_b.jpg


    a.方法内部收集代码示例

    private static void runRequest(int flow){
        ...
        /************************* 调用处不做处理 ***************************/
        String prefix = getPrefix(supportHttps);
    }
    
    private static String getPrefix(boolean supportHttps) {
        /************************* 方法内部收集参数信息 ***************************/
        try {
            //改变了supportHttps的值
            supportHttps = subCondition();
            return supportHttps ? "https" : "http";
        }finally {
            //方法内记录,其值会以方法内最后值为准,也就是方法内对该值进行变更会影响到记录的值
            recordParams(supportHttps);
        }
    }
    

    b.调用处收集代码示例

    private static void runRequest(int flow){
        ...
        /************************* 调用处收集参数信息 ***************************/
        try{
            String prefix = getPrefix(supportHttps);
        }finally {
            //调用处记录,此时 supportHttps 是值传递,因此方法内部值改变不会影响到此处记录的值
            recordParams(supportHttps);
        }
    
    }
    
    private static String getPrefix(boolean supportHttps) {
        /************************* 方法内部不做处理 ***************************/
        //改变了supportHttps的值
        supportHttps = subCondition();
        return supportHttps ? "https" : "http";
    }
    
    结果显而易见,在 方法结束之后 收集参数值的两种方法中,采用 方法内部收集 的时候,拿到的是方法内更改过的值,这也是Arthas采用的方式。

    五、写在最后

    当我们看到 方法结束之后的参数值的变化 时,很自然而然地想起考试和面试都出现较多的 值传递和地址传递 问题 ,也会很理所当然地认为,这个参数是不会变的;但是我们忽略了Arthas是怎么实现这个功能的,它的原理大致如何,进而导致一些误解的出现。

    作者:wingli
    链接: juejin.cn/post/70244080

    展开全文
  • 利用铁塔风梯度观测资料和超声风温仪观测资料,对2008年1月18-21日暴雪前后,湖北黄石长江岸边近地层风场和湍流作了计算分析,探索其异常变化特征,为认识黄石地区暴雪近地层发生发展的物理过程提供依据。...
  • 采用巴西劈裂实验和白光数字散斑相关方法,对泥岩在拉应力作用下的破坏过程进行观测,利用水泥对泥岩进行改性,研究了改性泥岩拉破坏过程的变化规律,并从微观角度分析了改性前后泥岩的拉破坏过程。结果表明:(1)改性的...
  • 基于双时间层的有限差分方法(ADI),建立了水深平均二维浅水潮流数学模型,采用逆风格式和追赶法求解二维浅水方程,通过建立钦州湾二维潮流数值模型重现钦州湾的潮位和潮流变化状况。模拟结果与同步进行的岸边潮位...
  • 采用趋势曲面拟合和统计方法研究了汶川地震1999~2007年区域网的应变积累,寻找震中的大致区域。除了昆仑山口西大地震震中及其周围地区外,2004~2007年震区域网的应变积累的趋势曲面拟合表明,汶川地震发生在...
  • 实验观测了短腔染料激光器输出的多纵模激光及其经一级染料放大的激光光谱,比较了光谱特性。在一定情况下,短腔染料激光器的多纵模激光经放大器放大可产生一个至几个新纵模,新纵模与短腔染料激光器输出的纵模有相似的...
  • 选取长江上游干、支流主要水文站为代表站,根据水文泥沙观测资料,对三峡水库进出库水沙特性进行了较为系统的分析,对比分析各站三峡工程蓄水前后年径流量、年输沙量、年均含沙量等水沙特征值的变化特性。...
  • 为了进行包容性确定,使用重夸克展开将衰减速率扩展为1 / m b,并从物理观测时刻开始,从实验数据中提取更高阶的重夸克参数,以评估| V cb | 从规范化。 缺点是这些可观察物在理论上和实验上都具有很高的相关性。 ...
  • 离散化的具体方法及证明参考现代控制论或计算机控制技术。这里只说明如何建模。 改写成连续状态空间方程形式 其中: 连续状态方程离散化 matlab代码如下: Ad=expm(AH*Tk) Bd = Ad*inv(AH)*([1 0;0 1]-inv...

    目录​​​​​​​

    控制对象

    连续对象离散化

    设计数字观测器

    考虑有限字长效应

    设计加法器

    缩放

    仿真文件下载地址:数字观测器_考虑有限字长效益-智慧交通文档类资源-CSDN下载


    控制对象

    W(s)=20 \frac{20 s+100}{s^{2}+14 s+100}

    连续对象离散化

    离散化的具体方法及证明参考现代控制论或计算机控制技术。这里只说明如何建模。

    改写成连续状态空间方程形式

    \begin{gathered} \dot{X}=A_{\mathrm{H}} * X(t)+B_{\mathrm{H}} * u(t) \\ y(t)=C_{\mathrm{H}} * X(t) \end{gathered}

    其中:A_{\mathrm{H}}=\left[\begin{array}{cc} 0 & 1 \\ -100 & -14 \end{array}\right], \quad B_{\mathrm{H}}=\left[\begin{array}{c} 0 \\ 20 \end{array}\right], \quad C_{\mathrm{H}}=\left[\begin{array}{ll} 100 & 20 \end{array}\right]

    连续状态方程离散化

    matlab代码如下:

    Ad=expm(AH*Tk)
    Bd = Ad*inv(AH)*([1 0;0 1]-inv(Ad))*BH

    simulink仿真图图下:

    离散化系统与原系统输出比较

    ​​​​​​​

    设计数字观测器

    全维数字状态观测器设计的计算可参考计算机控制技术

    判断系统可观性:

    >> rank(obsv(AH,C))
    
    ans =
    
         2

    系统可观 

    离散系统全维状态观测器方程

    \begin{aligned} &\hat{X}(n+1)=A^{*} \hat{X}(n)+K^{*} \varepsilon(n)+B^{*} u(n) \\ &y(n)=C^{*} \hat{X}(n) \end{aligned}

    其中\varepsilon (n+1)=(A-K * C) \varepsilon (n), \quad \varepsilon (0)=\varepsilon _{0}

    计算反馈矩阵G

    假设希望观测器的特征根\lambda位于\left|\lambda_{m}\right|^{5} \leq \lambda \leq\left|\lambda_{m}\right|^{3} 其中\lambda _{m}原状态方程特征根的最小值。使用maltab命令acker计算G

    lamdaA = eig(Ad);
    lamda = abs(max(eig(Ad)))^5+(abs(min(eig(Ad)))^3-abs(min(eig(Ad)))^5)*rand();
    Lamda = [lamda;lamda];
    %------------------------------------------------------------------------------%
    G = acker(Ad',C',Lamda);
    K = G'; 

    带观测器的simulink模型 

    考虑有限字长效应

    设计加法器

    数字观测器在物理实现时,计算硬件的位数是不无限的,因此设计观测器前需要考虑有限字长效应。在这个例子中考虑加法器的有限字长效应。上一小节中输出y最大值2831<2^12因此加法器的最大位数为12。

    设计加法器,使用simulink中的S-Function Builder 模块

    打开模块进行设置 ,加法器有两个输入一个输出一个参数如下图

     在/* Output_BEGIN */下方输入如下代码后编译

    %%%参数m 加法器的位数
    long x1,x2,M,n1;
    int n;
    n=m[0];
    M=1;
    while (n>0)
    {M=M*2;
    n--;}
    M=M-1;
    n1=u0[0];
    if(n1>=0) x1=n1&M;
    else x1= -((-n1)&M);
    n1=u1[0];
    if(n1>=0) x2=n1&M;
    else x2= -((-n1)&M);
    y0[0]=x1+x2;

    然后将原模型中的加法器替换如下图

     进行仿真

     可以看到观测器的输入与控制对象的输出在稳态时有误差,注意到图中的增益模块gain的系数很小使得进入到加法器的值很小,而加法器只能表示整数,因此导致较大的误差,为了解决这个问题,使用缩放方法减小稳态误差。

    缩放

    例如将状态x_{1},x_{2}分别缩小百分之80和20,则可以得到新的状态方程,其中dsAD = M^{-1}AdM ,BD = M^{-1}Bd,CD = CM,M=\begin{bmatrix} m1 & 0\\ 0 & m2 \end{bmatrix},m1=1/80,m2=1/20

    matlab 代码

    m1=1/80;
    m2=1/20;
    M=[m1 0;0 m2];
    AD = inv(M)*Ad*M
    BD = inv(M)*Bd
    CD = C*M
    

    simulink仿真图

    注意到此时增益数比原模型的要大一些,因此推断数字系统观测器的输出与原系统输出的稳态误差应该会减少。

      

    观测器与控制对象状态变量和输出的比较

    上图证明了推断,对系统状态变量的缩放的确可以降低有限字长效应的影响,并且注意到数字观测器和原系统的状态变量仍然存在稳态误差,因此缩放只是降低了误差而不是消除。

    仿真文件下载地址:数字观测器_考虑有限字长效益-智慧交通文档类资源-CSDN下载

    相关文章:

    使用simulink仿真连续(离散)线性定长系统全维渐进状态观测器_Giiwedin的博客-CSDN博客

    使用drem对控制系统进行参数估计simulink仿真_Giiwedin的博客-CSDN博客

    对给定干扰信号的simulink数字控制系统仿真_Giiwedin的博客-CSDN博客_simulink扰动信号

    二相混合式步进电机闭环矢量控制simulink仿真(含仿真文件)_Giiwedin的博客-CSDN博客_步进电机数学模型

    二相混合式步进电机开环细分控制simulink建模仿真含模型文件_Giiwedin的博客-CSDN博客

    二相混合式步进电机simulink仿真简单的驱动器建模(含模型文件)_Giiwedin的博客-CSDN博客_步进电机simulink模型

    展开全文
  • §3.4、水准观测的视线长度、前后视距差和视线高度(m) 4 §3.5 沉降观测测站限差及闭合差应符合表四的规定: 4 四、人员组织与观测方法: 4 §4.1 人员组织 4 §4.2 作业流程 5 §4.3 观测方法 5 五、 成果的检查...
  • 潮汐观测方法有哪些?

    2021-04-30 07:31:54
    验潮的目的是为了了解当地的潮汐性质,应用所获得的潮汐观测资料,计算该地区的潮汐调和常数、平均海面、深度基准面、潮汐预报以及提供测量不同时刻的水位改正数等潮汐观测方法有哪些?潮汐观测通常称为水位观测,又...
  • 实地观测数据表明,西藏晴天太阳红斑紫外线的剂量率随当日时间的变化呈典型的抛物线状,并且由于太阳高度角的增加,晴天太阳红斑紫外线的最大剂量率平均出现时间为当地正午前后约10 min。在理论上,从冬至起西藏晴天太阳...
  • VUE构建前后端分离的前端项目

    千次阅读 多人点赞 2020-08-26 23:26:18
    VUE构建前后端分离的前端项目(超详细) 1.使用vue-cli创建项目 2.使用elementUI组件编写页面 3.使用axios与后台交互 4.使用webpack构建工具打包 5.部署到Tomcat 1.技术背景 前后端分离的优势: 分工明确,提高...
  • 以大气垂直折光角及其起伏的日变化规律为基础,分析了折光角及其起伏在不同时间对垂直角观测值的不同影响,讨论了高精度垂直角的最佳观测时间问题:对于同时对向观测和单向观测,晴天日出、日落前后相对最佳,中午前后...
  • DSSS系统收发比特流比较,m序列解扩的信号时域和频域波形,发送序列的基本特性,接收扩频BPSK信号去载波调制,接收信号的频域波形,接收信号的时域波形,接收信号下变频对比,解扩前后的信号功率谱对比,解扩前后...
  • 针对2004年5月26日-2005年10月15日盘锦...芦苇湿地碳通量、感热通量和潜热通量的日动态呈单峰单谷型变化,极值出现在中午前后,夜间线形平直。芦苇生长季白天通量绝对值远较夜间大,白天碳吸收,夜间碳排放。CO2浓度年
  • 可移动唇罩式变几何进气道高超声速飞行器是指飞行器发动机前端设有一个能沿着来流方向前后平移的唇罩,从而能够实现飞行器的最大气流捕获,以提高发动机的机动性能.针对变几何进气道飞行器强非线性以及存在参数不确定...
  • 为了研究坚硬顶板工作面沿空留巷矿压显现规律,采用矿压观测方法,在沿空留巷过程中设置相应的测站,对留巷前后巷道围岩表面位移、人造帮受力及轴向变形进行观测分析。
  • 学习隐马尔可夫模型(HMM),主要就是学习三个问题:概率计算问题,学习问题和预测问题。概率计算问题主要是讲向算法和向算法,这两个算法可以说是隐马尔可夫的重中之重
  • 当下涉及前后端工程项目的研发,主流模式一定是前后端的分离。它让前后端的角色分工更加明确,对项目的研发质量提供了更好的保障。但同时也带来了诸多调试上的不便。 我们这里以 web 开发为例, 前后端工程分开,...
  • 该算法以脉冲前后沿为研究对象,通过分析观测新息和常推力α-β动力学模型中辅助变量β的物理特性,给出脉冲机动前后沿检测判据。仿真实验比较了χ2检测法和β检测法的特性,结果表明:χ2检测法,对机动前沿的敏感...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,210
精华内容 4,484
关键字:

后前前后的观测方法