IGH主站通信测试csp模式(DC同步 preemrt)连通一从站并实现控制

news2024/11/17 17:43:13

IGH主站通信测试

linuxcnc配置基础机器人控制LinuxCNC与EtherCAT介绍&&PDO&SDO,搭建环境步骤

需要配置IGH主站的查看这篇文章
linux系统学习笔记7——一次性安装igh-ethercat主站

CSP模式
DC同步方式
preemrt实时补丁

直接上代码,这部分是直接控制使用csp模式控制一个从站运动
使能后直接运动,10s,每秒607a(目标位置)增加100.
注意:急停 按下ESC

代码分为两部分,一个是通信线程 主要负责和伺服通信,使能伺服,读取和写入寄存器值。
第二个是操作线程, 负责修改位置的值,和监控按键。

使用此代码,首先根据手册
1.修改PDO条目 ,要和自己的伺服一致
2.修改 PID VID 的值
3.根据自己启动模式,修改6040的控制字,比如笔者的是csp模式,6040:6-7-15 才能使能。

/*********************************************************************
 * ethercat通讯驱动禾川伺服驱动器X3EB**********************************
 * IGH主站PRMEET RT*************************************************
 * HUALAI机械臂******************************************************
 * DC同步模式
 * csp同步周期位置模式
 * 通信成功后运动,急停按下ESC
 * 作者:sf9090
 * 时间:2023/3/1
 * *********************************************************
 * ********************************************************************
**********************************************************************/
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/mman.h>
#include <pthread.h>
#include <math.h>
#include <malloc.h>
#include <sched.h> /* sched_setscheduler() */
/****************************************************************************/
#include "ecrt.h"
#include <time.h>
/*-------------------------------------监听键盘----------------------------------*/
#include <termios.h>
#include <fcntl.h> 
/****************************************************************************/
#include <stdbool.h>


#define FREQUENCY 1000
#define TASK_FREQUENCY          10 /*Hz*/

#define     Bool                              int
#define     false                             0
#define     true                              1
#define     ETHERCAT_STATUS_OP                0x08
#define     STATUS_SERVO_ENABLE_BIT           (0x04)

#define     CLOCK_TO_USE         CLOCK_REALTIME
#define     NSEC_PER_SEC         (1000000000L)
static int64_t  system_time_base = 0LL;
struct timespec wakeupTime;

#define PERIOD_NS (NSEC_PER_SEC / FREQUENCY) /*本次设置周期PERIOD_NS为1ms*/

#define DIFF_NS(A, B)                                                          \
  (((B).tv_sec - (A).tv_sec) * NSEC_PER_SEC + (B).tv_nsec - (A).tv_nsec)

#define TIMESPEC2NS(T) ((uint64_t)(T).tv_sec * NSEC_PER_SEC + (T).tv_nsec)
//获取当前系统时间

//master status
typedef enum  _SysWorkingStatus
{
    SYS_WORKING_POWER_ON,
    SYS_WORKING_SAFE_MODE,
    SYS_WORKING_OP_MODE,
    SYS_WORKING_LINK_DOWN,
    SYS_WORKING_IDLE_STATUS       //系统空闲
}SysWorkingStatus;

typedef  struct  _GSysRunningParm
{
    SysWorkingStatus   m_gWorkStatus;
}GSysRunningParm;

GSysRunningParm    gSysRunning;

bool Isquit = true;/*判断是否停止*/
bool flag = false;
const int slave = 0;/*从站号*/
int SendNumber = 0;/*发送的次数*/
int ecstate = 0;/*循环次数,用来初始化主站的变量*/
bool IsRun = false;/*判断伺服是否使能*/
/****************************************************************************/

// EtherCAT
ec_master_t *master = NULL;
static ec_master_state_t master_state = {};

static ec_domain_t *domainServoInput = NULL;
static ec_domain_state_t domainServoInput_state = {};
static ec_domain_t *domainServoOutput = NULL;
static ec_domain_state_t domainServoOutput_state = {};

static uint8_t *domainOutput_pd = NULL;
static uint8_t *domainInput_pd = NULL;

static ec_slave_config_t *sc_estun;
static ec_slave_config_state_t sc_estun_state;
/****************************************************************************/
#define estun_Pos0 0, 0
#define estun  0x000116c7, 0x003e0402
// offsets for PDO entries
static unsigned int  errcode;

static unsigned int  cntlwd;/*控制字*/
static unsigned int  ipData;/*目标位置*/
static unsigned int  modes_of_operation;/*模式*/
static unsigned int  status;/*状态字*/
static unsigned int  actpos;/*实际位置*/
static unsigned int  modes_of_operation_display;/*读取模式*/
static unsigned int current_velocity;/*当前速度*/
static int cur_status;/*当前状态字*/
static int cur_mode;/*当前模式*/
static int curpos = 0;/*当前位置*/
int curpos_offset = 0;/*设置当前位置*/
// process data
static unsigned int counter = 0;
static unsigned int blink = 0;
static unsigned int sync_ref_counter = 0;
const struct timespec cycletime = {0, PERIOD_NS};
// 


ec_pdo_entry_reg_t domainServoOutput_regs[] = {

    {estun_Pos0, estun, 0x6040, 0x00, &cntlwd, NULL},
    {estun_Pos0, estun, 0x6060, 0x00, &modes_of_operation, NULL},           //6060 模式选择
    {estun_Pos0, estun, 0x607A, 0x00, &ipData, NULL},    
    {}

};
ec_pdo_entry_reg_t domainServoInput_regs[] = {
     {estun_Pos0, estun, 0x6041, 0x00, &status, NULL},
      {estun_Pos0, estun, 0x606C, 0x00, &current_velocity, NULL},
    {estun_Pos0, estun, 0x6064, 0x00, &actpos, NULL},
   
    {}
};
/*****************************************************************************/

// 两个时间相加
struct timespec timespec_add(struct timespec time1, struct timespec time2) {
  struct timespec result;

  if ((time1.tv_nsec + time2.tv_nsec) >= NSEC_PER_SEC) {
    result.tv_sec = time1.tv_sec + time2.tv_sec + 1;
    result.tv_nsec = time1.tv_nsec + time2.tv_nsec - NSEC_PER_SEC;
  } else {
    result.tv_sec = time1.tv_sec + time2.tv_sec;
    result.tv_nsec = time1.tv_nsec + time2.tv_nsec;
  }

  return result;
}
/*********************************************************
 * PDO条目根据伺服驱动器说明书上相应的模式设置
 * 查看ethercat cstruct
**********************************************************/
ec_pdo_entry_info_t estun_pdo_entries[] = {


    /*RxPdo 0x1600*/
    {0x6040, 0x00, 16},
    {0x6060, 0x00, 8 }, 
    {0x607a, 0x00, 32},
    /*TxPdo 0x1A00*/
    {0x6041, 0x00, 16},
    {0x606C, 0x00, 32},
    {0x6064, 0x00, 32}

};

ec_pdo_info_t estun_pdos[] = {
    {0x1600, 3, estun_pdo_entries + 0}, /* CoE CSP Mode (RX) */
    {0x1a00, 3, estun_pdo_entries + 3}, /* CoE CSP Mode (TX) */

};

ec_sync_info_t estun_syncs[] = {
    {0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},
    {1, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},
    {2, EC_DIR_OUTPUT, 1, estun_pdos + 0, EC_WD_ENABLE},
    {3, EC_DIR_INPUT, 1, estun_pdos + 1, EC_WD_DISABLE},
    {0xff}
};

/****************************************************************************/
int ConfigPDO()
{
    /********************/
    printf("  Configuring PDOs...\n");
    domainServoOutput = ecrt_master_create_domain(master);
    if (!domainServoOutput) {
        return -1;
    }
    domainServoInput = ecrt_master_create_domain(master);
    if (!domainServoInput) {
        return -1;
    }
    /********************/
    printf("  Creating slave configurations...\n");
    sc_estun =
        ecrt_master_slave_config(master, estun_Pos0, estun);
    if (!sc_estun) {
        fprintf(stderr, "Failed to get slave configuration.\n");
        return -1;
    }
    /********************/
    if (ecrt_slave_config_pdos(sc_estun, EC_END, estun_syncs)) {
        fprintf(stderr, "Failed to configure PDOs.\n");
        return -1;
    }
    /********************/
    if (ecrt_domain_reg_pdo_entry_list(domainServoOutput, domainServoOutput_regs)) {
        fprintf(stderr, "PDO entry registration failed!\n");
        return -1;
    }
    if (ecrt_domain_reg_pdo_entry_list(domainServoInput, domainServoInput_regs)) {
        fprintf(stderr, "PDO entry registration failed!\n");
        return -1;
    }

    fprintf(stderr, "Creating SDO requests...\n");
    //有些伺服没有sdo功能的不需要配置
    ecrt_slave_config_sdo8(sc_estun, 0x6060, 0, 8);
    ecrt_slave_config_sdo8(sc_estun, 0x60C2, 1, 1);

    return 0;
}


/*****************************************************************************
 * Realtime task
 ****************************************************************************/

void rt_check_domain_state(void)
{
    ec_domain_state_t ds = {};
    ec_domain_state_t ds1 = {};
    //domainServoInput
    ecrt_domain_state(domainServoInput, &ds);
    if (ds.working_counter != domainServoInput_state.working_counter) {
        printf("domainServoInput: WC %u.\n", ds.working_counter);
    }
    if (ds.wc_state != domainServoInput_state.wc_state) {
        printf("domainServoInput: State %u.\n", ds.wc_state);
    }
    domainServoInput_state = ds;
    //domainServoOutput
    ecrt_domain_state(domainServoOutput, &ds1);
    if (ds1.working_counter != domainServoOutput_state.working_counter) {
        printf("domainServoOutput: WC %u.\n", ds1.working_counter);
    }
    if (ds1.wc_state != domainServoOutput_state.wc_state) {
        printf("domainServoOutput: State %u.\n", ds1.wc_state);
    }
    domainServoOutput_state = ds1;
}

/****************************************************************************/

void rt_check_master_state(void)
{
    ec_master_state_t ms;

    ecrt_master_state(master, &ms);

    if (ms.slaves_responding != master_state.slaves_responding) {
        printf("%u slave(s).\n", ms.slaves_responding);
    }

    if (ms.al_states != master_state.al_states) {
        printf("AL states: 0x%02X.\n", ms.al_states);
    }

    if (ms.link_up != master_state.link_up) {
        printf("Link is %s.\n", ms.link_up ? "up" : "down");
    }

    master_state = ms;
}

/****************************************************************************/
void check_slave_config_states(void)
{
    ec_slave_config_state_t s;
    ecrt_slave_config_state(sc_estun,&s);
    if (s.al_state != sc_estun_state.al_state)
        printf("sc_estun_state: State 0x%02X.\n", s.al_state);
    if (s.online != sc_estun_state.online)
        printf("sc_estun_state: %s.\n", s.online ? "online" : "offline");
    if (s.operational != sc_estun_state.operational)
        printf("sc_estun_state: %soperational.\n",s.operational ? "" : "Not ");
    sc_estun_state = s;


}
/****************************************************************************/
void ReleaseMaster()
{
    if(master)
    {
        printf("  End of Program, release master\n");
        ecrt_release_master(master);
        master = NULL;
    }
}
/****************************************************************************/
int ActivateMaster()
{
    int ret;
    printf("  Requesting master...\n");
    if(master)
        return 0;
    master = ecrt_request_master(0);
    if (!master) {
        return -1;
    }

    ConfigPDO();

    // configure SYNC signals for this slave
    ecrt_slave_config_dc(sc_estun, 0x0300, 1000000, 0, 0, 0);
/********************************************************
 *       配置从站 sync0 和 sync1 信号
 * 最后四个参数表示设置 sync 0和1 的周期和相应的偏移量,单位都是 ns。
 *  sync0_cycle即为sync0的循环周期,和主栈的周期任务的循环周期保持一致。这个是很重要的一点,需要注意。

  * 1、查看 esi 文件,不支持 sync1 同步,所以需要设置成 0x0300
  * 0x300: 0x0981的 0,1 位 置 1,其他位 置 0,表示激活运行周期, 激活 sync0
 * 0x700: 0x0981的 0,1,2 位 置 1,其他位 置 0,表示激活运行周期, 激活 sync0,和 sync1 
  * 2、查看 ethercat upload 0x1c32 0x0004 中 bit5-6 为零,代表不支持 shift time,因此第三个参数设置为 0
 *  3、一般不使用sync1同步信号,最后两个参数可设置为0。
  * 同步周期设置成 1ms
 * ********************************************************/



    
    // ecrt_master_application_time(master, system_time_ns());
    ret = ecrt_master_select_reference_clock(master, NULL);
    if (ret < 0) {
        fprintf(stderr, "  Failed to select reference clock: %s\n",
                strerror(-ret));
        return ret;
    }

    /********************/
    printf("  Activating master...\n");
    if (ecrt_master_activate(master)) {
        printf("  Activating master...failed\n");
        return -1;
    }
    /********************/
    if (!(domainInput_pd = ecrt_domain_data(domainServoInput))) {
        fprintf(stderr, "  Failed to get domain data pointer.\n");
        return -1;
    }
    if (!(domainOutput_pd = ecrt_domain_data(domainServoOutput))) {
        fprintf(stderr, "  Failed to get domain data pointer.\n");
        return -1;
    }
    printf("  Activating master...success\n");
    return 0;
}
/******************************************************************************
 * 判断是否有按键按下
******************************************************************************/
int kbhit()
{
        struct termios oldt, newt;

        int ch;

        int oldf;

        tcgetattr(STDIN_FILENO, &oldt);

        newt = oldt;

        newt.c_lflag &= ~(ICANON | ECHO);

        tcsetattr(STDIN_FILENO, TCSANOW, &newt);

        oldf = fcntl(STDIN_FILENO, F_GETFL, 0);

        fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

        ch = getchar();

        tcsetattr(STDIN_FILENO, TCSANOW, &oldt);

        fcntl(STDIN_FILENO, F_SETFL, oldf);

        if(ch != EOF)

        {

            ungetc(ch, stdin);

            return 1;

        }

        return 0;

}
/*******************************************************************************/


/****************************************************************************
 * 按键定义
 * ESC:退出程序
 * 
 ***************************************************************************/
void listen_button()
{

        
    char key;
    if(kbhit())//检测是否有键盘输入
    {

        key=getchar();
        
        printf(" key = %d \n",key);
        if(key==27)//esc键的ASCII为27
        { 
            printf("退出程序\n");
           curpos_offset  = 0;
            Isquit = false;

        }
     
    }
    
}
/*********************************************
 * 操作线程
*********************************************/
void *OperationThread(void * arg)
{
    while(1)
    {
        usleep(10000);
        listen_button();
        if(!Isquit){
            IsRun  = false;
            ReleaseMaster();
            exit(0);
        }
        if ( IsRun){//如过伺服驱动器使能,这里就开始运行,知道10s后会停止运动,这里运动是通过修改607a的值实现
            if(SendNumber >= 10000)
                curpos_offset  = 0;
           else
                curpos_offset=100.0;
        }      
    }
}
/*******************************************************************************/

/****************************************************************************/


/****************************************************************************/
 void DriverEtherCAT()
{
    static int i = 0;
    int status1= 0;
   
    //处于刚开机(需要等待其他操作完成),返回等待下次周期
    if(gSysRunning.m_gWorkStatus == SYS_WORKING_POWER_ON)
        return ;

    static int cycle_counter = 0;
    cycle_counter++;
    if(cycle_counter >= 120*1000){
        cycle_counter = 0;

    }

    // receive EtherCAT frames
    ecrt_master_receive(master);
    ecrt_domain_process(domainServoOutput);
    ecrt_domain_process(domainServoInput);
    rt_check_domain_state();

    if (!(cycle_counter % 500)) {
        rt_check_master_state();
        check_slave_config_states();
    }
    curpos = EC_READ_S32(domainInput_pd + actpos);  
    //状态机操作
    switch (gSysRunning.m_gWorkStatus)
    {
    case SYS_WORKING_SAFE_MODE:{
        //检查主站是否处于 OP 模式, 若不是,则调整为 OP 模式
        rt_check_master_state();
        check_slave_config_states();
        if((master_state.al_states & ETHERCAT_STATUS_OP))
        {
            int tmp = true;

            if(sc_estun_state.al_state != ETHERCAT_STATUS_OP)
            {
                tmp = false;
                break ;
            }

            if(tmp)
            {
                ecstate = 0;
                gSysRunning.m_gWorkStatus = SYS_WORKING_OP_MODE;
                printf("  SYS_WORKING_OP_MODE\n");
            }
        }
    }break;

    case SYS_WORKING_OP_MODE:
    {
        ecstate++;
        //使能伺服
        if(ecstate <= 900)
        {
            switch (ecstate){
            case 1:
                EC_WRITE_U8(domainOutput_pd + modes_of_operation, 8);
                break;
            case 200:
            //    EC_WRITE_U16(domainOutput_pd + cntlwd, 0x80);    //错误复位  
                cur_status=  EC_READ_U16(domainOutput_pd+ cntlwd);
                printf(" my status_world 0X6040 = %d\n",cur_status);
                cur_status = EC_READ_U16(domainInput_pd + status);
                printf(" my status_world 0x6041 = %d\n",cur_status);
         
                break;
            case 300:
               curpos = EC_READ_S32(domainInput_pd + actpos);  
               EC_WRITE_S32(domainOutput_pd + ipData, curpos);
                printf("x@rtITP >>> Axis  current position = %d\n", curpos);

                break;
            case 400:
                EC_WRITE_U16(domainOutput_pd + cntlwd, 0x06);
               status1=  EC_READ_U16(domainInput_pd+ status);
                printf(" my status_world 0X6041 = %d \n",status1);
                break;
            case 500:
                EC_WRITE_U16(domainOutput_pd + cntlwd, 0x07);
                status1=  EC_READ_U16(domainInput_pd+ status);
                printf(" my status_world 0X6041 = %d \n",status1);
                break;
            case 600:

                EC_WRITE_U16(domainOutput_pd + cntlwd, 0xF);
                status1=  EC_READ_U16(domainInput_pd+ status);
                printf(" my status_world 0X6041 = %d \n",status1);
                break;              
            }

        }
        else {
         
            printf("enable servo success!\n");

            int tmp  = true;
            if((EC_READ_U16(domainInput_pd + status) & (STATUS_SERVO_ENABLE_BIT)) == 0)
            {
                tmp = false;
                printf("EC_READ_U16(domainInput_pd + status) & (STATUS_SERVO_ENABLE_BIT)==0\n");
                break ;
            }
            if(tmp)
            {
                ecstate = 0;
                gSysRunning.m_gWorkStatus = SYS_WORKING_IDLE_STATUS;
                printf("  SYS_WORKING_IDLE_STATUS\n");              
            }
        }
    }break;
    default://  在周期任务里,判断当电机切换为使能状态后,读取电机当前位置,并把这个数值加数据域设置目标作为目标位置写入电机
    {
       
        IsRun = true;       
        EC_WRITE_S32(domainOutput_pd + ipData,curpos+curpos_offset );//  下发位置命令
        SendNumber++;
    }break;
 
    }
 
    // write application time to master

    // ecrt_master_application_time(master, system_time_ns());
    ecrt_master_sync_reference_clock(master);  //将指定的时间发送给参考时钟,这个函数将最近一次从ecrt_master_application_time传入的时间戳发送给参考时钟。
      // 这就是官方example中除了rtai_rtdm_dc这个例子使用的默认dc同步方式,即所谓的以主站作为参考时钟的方式。

    ecrt_master_sync_slave_clocks(master);          //将DC时钟漂移补偿数据报排队发送,让所有从站时钟与基准时钟同步

    // send process data
    ecrt_domain_queue(domainServoOutput);
    ecrt_domain_queue(domainServoInput);
    ecrt_master_send(master);
}
/****************************************************************************/

void *InterpolationThread(void * arg)
{
   clock_gettime(CLOCK_TO_USE, &wakeupTime);
    while (1) {
        usleep(10000);
        wakeupTime = timespec_add(wakeupTime, cycletime);

    // TIMER_ABSTIME: 代表是采用的绝对时间
    // 最后一个参数 rept的意思: 该函数将会使得调用进程处于挂起状态,直到请求的时间到达或者是被信号中断,参数reqtp指定了需要睡眠的秒数与纳秒数。
    // 如果在睡眠中途被信号中断,且进程没有终止的话,timespec结构指针remtp指向的结构将保存剩余的睡眠时间,如果我们对于未睡眠时间不感兴趣的话,我们可以把这一时间设置为NULL.
    // 如果系统不支持纳秒时间精度的话,请求时间将被向上取整,因为函数nanosleep并不涉及任何信号的产生,我们可以放心大胆地使用它而不用担心与其他函数相互影响。
         clock_nanosleep(CLOCK_TO_USE, TIMER_ABSTIME, &wakeupTime, NULL);
         ecrt_master_application_time(master, TIMESPEC2NS(wakeupTime));
        //Delay the calling task (absolute).Delay the execution of the calling task until a given date is reached.
 
        DriverEtherCAT();
    }
}



/****************************************************************************
 * Main function
 ***************************************************************************/

int main(int argc, char *argv[])
{
    int ret;

   mlockall(MCL_CURRENT | MCL_FUTURE);

    gSysRunning.m_gWorkStatus = SYS_WORKING_POWER_ON;
    if(gSysRunning.m_gWorkStatus == SYS_WORKING_POWER_ON)
    {
        ActivateMaster();
        ecstate = 0;
        gSysRunning.m_gWorkStatus = SYS_WORKING_SAFE_MODE;
        printf("  SYS_WORKING_SAFE_MODE\n");
    }


    printf("Starting InterpolationTask...\n");

    pthread_t id[3];
    int i = 0;
    pthread_create(&id[0],NULL,InterpolationThread,NULL);//通讯线程
    pthread_create(&id[1],NULL,OperationThread,NULL);//操作线程
    pthread_join(id[0],NULL);
    pthread_join(id[1],NULL);
    printf("  Deleting realtime InterpolationTask task...\n");

    return 0;
}

参考:https://blog.csdn.net/weixin_40293570/article/details/108712655

有问题可以在博客下方留言,或者关注微信公众号私信
【关注微信公众号一起来交流】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/380960.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

YOLOV7模型调试记录

先前的YOLOv7模型是pytorch重构的&#xff0c;并非官方提供的源码&#xff0c;而在博主使用自己的数据集进行实验时发现效果并不理想&#xff0c;因此生怕是由于源码重构导致该问题&#xff0c;此外还需进行对比实验&#xff0c;因此便从官网上下载了源码&#xff0c;进行调试运…

二叉树——二叉搜索树中的插入操作

二叉搜索树中的插入操作 链接 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和要插入树中的值 value &#xff0c;将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 &#xff0c;新值和原始二叉搜索树中的任意节点值都不同。 注意&#xff0c…

配置二层远程端口镜像案例

实验拓扑&#xff1a; 实验需求&#xff1a; 如图1所示&#xff0c;某公司行政部通过SwitchA与外部Internet通信&#xff0c;监控设备Server通过SwitchB与SwitchA相连。 现在希望Server能够远程对行政部访问Internet的流量进行监控。 操作步骤&#xff1a; 配置观察端口 # 在…

C/C++开发,无可避免的多线程(篇一).跨平台并行编程姗姗来迟

一、编译环境准备 在正式进入c/c多线程编程系列之前&#xff0c;先来搭建支持多线程编译的编译环境。 1.1 MinGW&#xff08;win&#xff09; 进入Downloads - MinGW-w64下载页面&#xff0c;选择MinGW-w64-builds跳转下载&#xff0c; 再次进行跳转&#xff1a; 然后进入下载页…

Fiddler抓包之Fiddler过滤器(Filters)调试

Filters&#xff1a;过滤器&#xff0c;帮助我们过滤请求。 如果需要过滤掉与测试项目无关的抓包请求&#xff0c;更加精准的展现抓到的请求&#xff0c;而不是杂乱的一堆&#xff0c;那功能强大的 Filters 过滤器能帮到你。 2、Filters界面说明 fiddler中的过滤 说明&#…

新增2000w播放、单月涨粉80w!13秒短视频竟成B站热门

知识区自从被设立为一级分区后&#xff0c;B站就成了大家口中的“互联网大学”&#xff0c;有什么不懂的知识就习惯上B站搜一搜、查一查。根据B站官方出具的创作者报告数据显示&#xff0c;除了众多自发原创知识作品的UP主以外&#xff0c;还有超过300位名师学者加入B站&#x…

【亲测可用】BEV Fusion (MIT) 环境配置

CUDA环境 首先我们需要打上对应版本的显卡驱动&#xff1a; 接下来下载CUDA包和CUDNN包&#xff1a; wget https://developer.download.nvidia.com/compute/cuda/11.6.2/local_installers/cuda_11.6.2_510.47.03_linux.run sudo sh cuda_11.6.2_510.47.03_linux.runwget htt…

pytorch-softmax解决分类问题,用fashion-mnist为例子,再走一遍数据获取到模型预测的流程。深度了解分类指标的递进关系

softmax回归 线性回归模型适用于输出为连续值的情景。在另一类情景中&#xff0c;模型输出可以是一个像图像类别这样的离散值。对于这样的离散值预测问题&#xff0c;我们可以使用诸如softmax回归在内的分类模型。和线性回归不同&#xff0c;softmax回归的输出单元从一个变成了…

当ChatGPT遇见Python

在如火如荼的 ChatGPT 大潮当中&#xff0c;已经衍生出了各种各样的周边产品。Python 作为著名的万金油工具&#xff0c;怎么能没有它的身影呢。今天我们就介绍两种通过 Python 调用 ChatGPT 的方法&#xff0c;一起来看看吧~chatgpt-wrapper这是一个开源在 GitHub 上的项目&am…

leetcode 236. 二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一个节点也可以是它自己的祖…

华为机试题:HJ86 求最大连续bit数(python)

文章目录&#xff08;1&#xff09;题目描述&#xff08;2&#xff09;Python3实现&#xff08;3&#xff09;知识点详解1、input()&#xff1a;获取控制台&#xff08;任意形式&#xff09;的输入。输出均为字符串类型。1.1、input() 与 list(input()) 的区别、及其相互转换方…

Linux下 C/C++ NTP网络时间协议详解

NTP&#xff08;Network Time Protocol&#xff0c;网络时间协议&#xff09;是由RFC 1305定义的时间同步协议。它是通过网络在计算机系统之间进行时钟同步的网络协议。NTP 在公共互联网上通常能够保持时间延迟在几十毫秒以内的精度&#xff0c;并在理想条件下&#xff0c;它能…

Molecule:使用Jetpack Compose构建StateFlow流

Molecule:使用Jetpack Compose构建StateFlow流 看下面的jetpack compose片段&#xff1a; Composable fun MessageCard(message: Message) {Column {Text(text message.author)Text(text message.body)} }这段代码最有趣的部分是它实际上是reactive。其反应性为 通过Composa…

树链剖分(维护树上信息)

学习前请先掌握线段树&#xff1a;线段树&#xff08;维护区间信息&#xff09; 一&#xff0c;思想&#xff1a; 将一颗树拆成多条线性链以方便维护&#xff08;如线段树&#xff09;。 先给出以下定义&#xff08;通过这些定义我们就可以组成链&#xff09;&#xff1a; …

Docker概念介绍

目录 1、传统方式、虚拟化、容器部署方式的区别 2、为什么会有docker 3、什么是docker 4、docker的优势 5、Docker组成部分 6、docker镜像的原理介绍 7、 容器应用场景 8、Docker资源汇总 了解docker之前&#xff0c;我们要先了解部署方式有哪些&#xff0c;各有什么优缺点…

Windows 右键菜单扩展容器 [开源]

今天给大家分享一个我做的小工具&#xff0c;可以自定义扩展右键菜单的功能来提高工作效率&#xff0c;效果图如下&#xff1a; 如上图&#xff0c;右键菜单多了几个我自定义的菜单&#xff1a; 复制文件路径 复制文件夹路径 我的工具箱 <走配置文件动态创建子菜单&#x…

cesium封装实现配置格网及插值高程面实现

一、数据结构建模二、插值算法得到的插值结果三、图层配置primitiveGrid:{isRLayerPanel: true,primitives:[],url: /static/data/Grid.json,dataPath: ,dataIdField: code,options:{id:primitiveGrid,name:格网,type:grid,isShow: false},location: {"destination":…

Hive中的基础函数(一)

一、hive中的内置函数根据应用归类整体可以分为8大种类型。 1、 String Functions 字符串函数 主要针对字符串数据类型进行操作&#xff0c;比如下面这些&#xff1a; 字符串长度函数&#xff1a;length •字符串反转函数&#xff1a;reverse •字符串连接函数&#xff1a;…

Word处理控件Aspose.Words功能演示:使用 C++ 在 Word 文档 (DOC/DOCX) 中插入表格

Aspose.Words 是一种高级Word文档处理API&#xff0c;用于执行各种文档管理和操作任务。API支持生成&#xff0c;修改&#xff0c;转换&#xff0c;呈现和打印文档&#xff0c;而无需在跨平台应用程序中直接使用Microsoft Word。此外&#xff0c; Aspose API支持流行文件格式处…

基于python的多线程数据库数据录入

说明&#xff1a; 使用python编程结合多线程技术&#xff0c;将已经在python文件中的数据批量写入到数据库&#xff0c;便于数据关系结构化管理。 环境配置&#xff1a; certifi2019.6.16 chardet3.0.4 idna2.8 PyMySQL0.9.3 requests2.22.0 urllib31.25.3 将所需要的环境保…