CANOpen,关于 DS402 电机驱动器的状态切换(控制字&状态字)

CANopen对于运动控制来说是一款优秀的通讯协议,采用了面向对象的一些设计思路,比如对象字典,过程数据对象(PDO),服务数据对象(SDO)等等。CANopen定义了完整的同步控制机制,使其成为主流的运动控制协议,除了在CAN总线上运行外,还被搬到了以太网上(CANopen over Ethernet),形成了著名的PowerLink,EtherCat工业以太网协议(CoE)。

一般支持ethercat的驱动器用的都是CoE协议,在配置好PDO后,ethercat的domain中包含了映射的Object Dictionary数据,通过读写domain即可读写对象字典中的对应数据,其中最主要的两个参数( 控制字状态字) 的简单使用如下:

控制字用于控制驱动器的各种状态切换(其中过程 0 和 过程 1 是还有 Error Occurs 都是自动切换的,其他状态切换一般需要通过写驱动器的控制字来完成):
CANOpen,关于 DS402 电机驱动器的状态切换(控制字&状态字)_第1张图片
各个状态的解释如下:
CANOpen,关于 DS402 电机驱动器的状态切换(控制字&状态字)_第2张图片

以下是各个状态切换的条件,其中 Bit0、Bit1 等所指的是控制字的对应位:

CANOpen,关于 DS402 电机驱动器的状态切换(控制字&状态字)_第3张图片

CANOpen,关于 DS402 电机驱动器的状态切换(控制字&状态字)_第4张图片

控制字各bit表示的含义:
CANOpen,关于 DS402 电机驱动器的状态切换(控制字&状态字)_第5张图片

状态字各bit表示的含义:
CANOpen,关于 DS402 电机驱动器的状态切换(控制字&状态字)_第6张图片

这是一段关于状态迁移的简易代码(读状态字并且写控制字)

    switch(cmd)
    {
    case ServoCommandOFF: // init value: If in Switch_On_Disabled state, change to Ready_To_Switch On
    {
        output.control_word_ = 0x06;  // operation: Shut down
        break;
    }
    case ServoCommandON:
    {
        if( (input.status_word_ & 0x0040) == 0x0040 )
        {
            output.control_word_ =  0x06;  // operation: Shut down
        }
        else if ( (input.status_word_&0x007f) == 0x0031 )  // FSA State: Ready to Switch On
        {
            output.control_word_ = 0x07;  // operation: Switch On
        }
        break;
    }
    case ServoCommandEnable:  // 上使能
    {
        if ( (input.status_word_&0x007b) == 0x0033 )  // FSA State: Switch On
        {
            output.control_word_ = 0x0f;   // Enable Operation
        }
        else
        {
            output.control_word_ =  0x0b; // 急停, Quick Stop
        }
        break;
    }
    case ServoCommandDisable:  // 下使能
    {
        output.control_word_ = 0x07; // Disable operation
        break;
    }
    case ServoCommandEmeStop:  // 急停
    {
        output.control_word_ = 0x0b; // 急停, Quick Stop
        break;
    }
    case ServoCommandFaultReset:  // 错误恢复, 错误恢复后需要重新使能
    {
        if( (input.error_code_!= 0) || (input.status_word_&0x0008) )
        {
            output.control_word_ =  output.control_word_ | 0x0080;
        }
        else
        {
            output.control_word_ =  output.control_word_ & 0xff7f;
        }
        break;
    }
    case ServoCommandHalt:  // 暂停 Halt On; Warning!!! 在暂停驱动器之前确保控制器已经停止发送位置指令
    {
        output.control_word_ = output.control_word_ | 0x0100;
        break;
    }
    case ServoCommandHaltReset:  // 取消暂停 Halt Off, Warning!!!
    {
        output.control_word_ = output.control_word_ & 0xfeff;
//        if ( (input.status_word_& 0x007f) == 0x0037)  // FSA State: Operation enabled (正常工作状态) = Switch On + Enable Operation + Quick Stop Off + No warning + Voltage On
//        {
//        output.target_cmd_ = data_->out.pos;
//        }
        break;
    }
    default:
        output.control_word_ = 0x0b; // 急停, Quick Stop
        break;
    }

当然,除了用一堆if..else也可以用有限状态机来实现啊,ref link: http://blog.csdn.net/gw569453350game/article/details/50427937

你可能感兴趣的:(c/c++,ethercat,Robotics,机器人)