无人机巡线(1)

2023-05-16

/*
本程序完成2020年电赛试题主要内容

如果用户认为已经掌握该文件使用方法,请删除此文件,然后添加FollowLine.c文件

1.拿到了绿色的数据;
2.
*/

#include "FollowLine.h"
#include "HARDWARE_uart.h"
#include "stdbool.h"
#include "pid.h"
#include "timer_drv.h"
#include "myMath.h"
#include "gcs.h"
#include "sdk.h"
#include "stdbool.h"
//#include "program_ctrl.h"

extern Usart_t UsartGroup[Num_USART];
extern PIDInfo_t PIDGroup[emNum_Of_PID_List];
extern UAV_info_t g_UAVinfo;
bool FollowLine = false;
bool FollowApriTag = false;

bool is_set_round(float first_angle, float current_angle);
void proControl(int16_t Distance, int16_t Speed);
void TimeoutCheck(void);
void UpdateStatus(void);
void UpdateAction(float dt);
void UpdateButton(void);
void ActionHoldPoint(int8_t Err, int16_t HoldTime, FSMList_t NextAction);
bool ActionFormChange(int8_t HoldTime, FormType_t TargetFormType, FSMList_t NextAction);
void UpdateDebugInfo(void);
void HoldCurrentPostion(float dt);
void HoldYawAngle(float dt);
float update_yaw_info_in_360(void);
FollowManager_t FollowManager;
SonarManager_t SonarManager;

/*
        |+X
        |
        |
+Y------------- -Y
        |
        |
        |-X
*/

void Follow_Init()
{
    FollowManager.ptrPIDInfoV = &PIDGroup[emPID_FolloLinePosVertically];
    FollowManager.ptrPIDInfoH = &PIDGroup[emPID_FolloLinePosHorizontally];
    FollowManager.ptrPIDInfoY = &PIDGroup[emPID_FollowSpdYaw];

    FollowManager.ptrPIDInfoV->kp = 1.5f;
    FollowManager.ptrPIDInfoH->kp = 1.5f;

    FollowManager.ptrPIDInfoH->DeathArea = 3;
    FollowManager.ptrPIDInfoV->DeathArea = 3;

    PIDGroup[emPID_FolloLineSpdVertically].kp = 0.45f;
    PIDGroup[emPID_FolloLineSpdVertically].ki = 0.13f;
    PIDGroup[emPID_FolloLineSpdVertically].kd = 0.014f;

    PIDGroup[emPID_FolloLineSpdHorizontally].kp = 0.45f;
    PIDGroup[emPID_FolloLineSpdHorizontally].ki = 0.13f;
    PIDGroup[emPID_FolloLineSpdHorizontally].kd = 0.014f;

    PIDGroup[emPID_FolloLinePosVertically].desired = 60 / 2;
    PIDGroup[emPID_FolloLinePosHorizontally].desired = 80 / 2;

    FollowManager.ptrPIDInfoH->OutLimitHigh = 20;
    FollowManager.ptrPIDInfoH->OutLimitLow = -20;
    FollowManager.ptrPIDInfoV->OutLimitHigh = 20;
    FollowManager.ptrPIDInfoV->OutLimitLow = -20;

    FollowManager.CountDownNumMs = MAX_COUNTDOWN;
    FollowManager.TargetAltitudeCM = TARGETALTITUDECM;

    FollowManager.FrontOpenmvFramePtr = (OpenMVFrame_t *)UsartGroup[UART_A1].RxBuff;
    FollowManager.GroundOpenmvFramePtr = (OpenMVFrame_t *)UsartGroup[UART_A3].RxBuff;
    FollowManager.ptrUAVInfo = &g_UAVinfo;

    P1DIR &= ~(1 << BIT1);
    MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1);
    P1DIR &= ~(1 << BIT4);
    MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN4);

    FollowManager.ptrPIDInfoY->kp = 0.02f;
    FollowManager.ptrPIDInfoY->ki = 0.001f;

    FollowManager.ptrPIDInfoY->OutLimitLow = -0.5;
    FollowManager.ptrPIDInfoY->OutLimitHigh = 0.5;
    FollowManager.ptrPIDInfoY->desired = 160 / 2;
}

//以100hz的速度轮询 10ms
void UpdateCentControl(float dt)
{
    //判断OpenMV返回的数据是否可用,有的时候OpenMV会返回无效数据
    if (FollowManager.GroundOpenmvFramePtr->CentPoint.x1 > 200 || FollowManager.GroundOpenmvFramePtr->CentPoint.y1 > 200)
        return;

    //更新距离
    FollowManager.distance = FollowManager.FrontOpenmvFramePtr->cnt1 | FollowManager.FrontOpenmvFramePtr->Target >> 8;

    //更新按钮控制实践
    UpdateButton();

    //更新程控状态线
    UpdateStatus();

    //更新程控动作线
    UpdateAction(dt);
}

float angle_temp_dt = 0;
//此函数只做状态判断和状态更新
void UpdateStatus()
{
    uint16_t distance = 0;
    static float pre_yaw_temp = 0;
    static int cnt = 0;

    //根据ActionList的内容,进入不同的状态
    switch (FollowManager.ActionList)
    {
    //判断
    case ActionWaitting:
        //Do nothing;
        break;

    //倒计时状态
    case ActionCountdown:
    {
        //倒计时,数据初始填充位于Follow_Init中
        FollowManager.CountDownNumMs--;

        //当倒计时结束时候,状态变更为ActionTakeOff
        if (FollowManager.CountDownNumMs <= 0)
        {
            FollowManager.ActionList = ActionTakeOff;
        }
    }
    break;

    //自动起飞状态
    case ActionTakeOff:
    {
        //自动起飞动作持续时间为5s(500 * 10ms = 5000ms = 5s),然后跳到ActionHoverStartPoint动作;
        ActionHoldPoint(MAX_HOVER_ERR, 500, ActionHoverStartPoint);
    }
    break;

    //悬停三秒开始前进并巡线
    case ActionHoverStartPoint:
        ActionHoldPoint(MAX_HOVER_ERR, 200, ActionFindLine);
        //        ActionHoldPoint(MAX_HOVER_ERR, 200, ActionFindLandSpace);
        break;
    case ActionFindLine:
        // 开始前进
        // 是否发现第一个圆形?
        if (FollowManager.GroundOpenmvFramePtr->FormType == Cirle)
        {
            //      是
            //      停止自旋

            //      跳到下一个动作
            FollowManager.ActionList = ActionCloseToCirle;
            //            FollowManager.ActionList = ActionResetAngle;
            //            FollowManager.ActionList = ActionTest;
        }
        break;
		case ActionCloseToCirle:
        //悬停在第一个圆形上
				//动作:hold在第一个圆形上2秒
        ActionHoldPoint(MAX_HOVER_ERR, 500, ActionGoForward);
        break;
    case ActionGoForward:
        // 目标:保持黑色竖线端点在画面中心
        // 向前走,并且控制PID进行左右调整
        // 是否找到圆形降落点
        //      是
        //      跳到下一个动作

        if (FollowManager.GroundOpenmvFramePtr->FormType == Cirle)
        {
            cnt++;

            FollowManager.ActionList = ActionResetFind2Cirle;

         //   pre_yaw_temp = g_Attitude.yaw;
        }
        break;


    case ActionResetFind2Cirle:
			//向前移动一小段距离,寻找第二个圆形降落点
		//悬停
		//
		if (FollowManager.GroundOpenmvFramePtr->FormType == Cirle)
        {
            cnt++;

            FollowManager.ActionList = ActionResetFind2Cirle;

         //   pre_yaw_temp = g_Attitude.yaw;
        }
        ActionHoldPoint(MAX_HOVER_ERR, 200, ActionFindLandSpace);

        break;
		
    case ActionFindLandSpace:
        // 是否发现降落点,这里识别下视的OpenMV的数据是否找到
        // 是
        // 切换到降落模式
        if (FollowManager.GroundOpenmvFramePtr->FormType == Cirle)
        {
            FollowManager.ActionList = ActionPreLand;
        }
        break;
    case ActionPreLand:
        ActionHoldPoint(MAX_HOVER_ERR, 200, ActionLand);
        break;

    //自动降落状态倒计时结束以后,进入上锁动作
    case ActionLand:
    {
        //倒计时逻辑
        static int Cnt = MAX_TIMEOUT1;

        if (Cnt-- < 0)
        {
            FollowManager.ActionList = ActionLock;
        }
    }
    break;

    //上锁动作
    case ActionLock:
        FollowManager.ActionList = ActionWaitting;
        break;
    default:
        break;
    }
}

extern float PIDGroup_desired_yaw_pos_tmp;






//只执行动作
void UpdateAction(float dt)
{
    static float last_yaw = 0;
    switch (FollowManager.ActionList)
    {
    //倒计时命令
    case ActionWaitting:
        //Do nothing7
        break;

    //自动起飞命令
    case ActionTakeOff:
        sdk_takeoff(80);
        break;

    //悬停命令
    case ActionHoverStartPoint:
        //起飞
        {
        }
        break;
    case ActionFindLine:
        sdk_velocity_set(15.0,5);
        break;
    case ActionGoForward:
        sdk_yaw_stop();
        sdk_velociyt_x_set(15);

        if (FollowManager.FrontOpenmvFramePtr->FormType == Pole)
        {
            HoldYawAngle(dt);
        }
        else
        {
        }
        break;
    case ActionTurnRound:
        sdk_velocity_reset();
        if (FollowManager.FrontOpenmvFramePtr->FormType == Pole)
        {
            HoldYawAngle(dt);
        }

        if (FollowManager.distance != 0xFF && FollowManager.distance != 20 && FollowManager.distance != 0)
        {
            if (FollowManager.distance > 65)
            {
                sdk_velociyt_x_set(15);
            }
            else if (FollowManager.distance < 35)
            {
                sdk_velociyt_x_set(-15);
            }
            else
            {
                sdk_velociyt_x_set(0);
            }
        }

        sdk_velociyt_y_set(10);
        break;
    case ActionResetV:
        sdk_velocity_reset();
        break;
    case ActionFindLandSpace:
        sdk_velocity_reset();
        sdk_velocity_set(10, 0);
        break;

    case ActionPreLand:
        HoldCurrentPostion(dt);
        break;
    case ActionTest:
        sdk_velociyt_x_set(15);
        //        sdk_yaw_stop();
        //        sdk_yaw_set(-180);
        break;
    case ActionGoLeft:

        break;
    case ActionGoBack:
        break;
    //自动降落
    case ActionLand:
        //降落命令
        sdk_land();
        HoldCurrentPostion(dt);
        break;

    //上锁动作
    case ActionLock:
        //        g_UAVinfo.FMUflg->unlock = 0;
        break;
    default:
        break;
    }
}

void HoldCurrentPostion(float dt)
{
    static float OldPos[2];
    //对输入做LPF

    //更新测量点
    PIDGroup[emPID_FolloLinePosVertically].measured = FollowManager.GroundOpenmvFramePtr->CentPoint.y1;
    PIDGroup[emPID_FolloLinePosHorizontally].measured = FollowManager.GroundOpenmvFramePtr->CentPoint.x1;

    PIDGroup[emPID_FolloLineSpdVertically].measured = (FollowManager.GroundOpenmvFramePtr->CentPoint.y1 - OldPos[0]);
    PIDGroup[emPID_FolloLineSpdHorizontally].measured = (FollowManager.GroundOpenmvFramePtr->CentPoint.x1 - OldPos[1]);

    OldPos[0] = FollowManager.GroundOpenmvFramePtr->CentPoint.y1;
    OldPos[1] = FollowManager.GroundOpenmvFramePtr->CentPoint.x1;

    UpdatePID(FollowManager.ptrPIDInfoH, dt); //PID
    UpdatePID(FollowManager.ptrPIDInfoV, dt); //PID

    PIDGroup[emPID_FolloLineSpdVertically].desired = FollowManager.ptrPIDInfoV->out;
    PIDGroup[emPID_FolloLineSpdHorizontally].desired = FollowManager.ptrPIDInfoH->out;

    UpdatePID(&PIDGroup[emPID_FolloLineSpdHorizontally], dt); //PID
    UpdatePID(&PIDGroup[emPID_FolloLineSpdVertically], dt);   //PID

    sdk_velocity_set(PIDGroup[emPID_FolloLineSpdVertically].out, PIDGroup[emPID_FolloLineSpdHorizontally].out);
}

bool ActionFormChange(int8_t HoldTime, FormType_t TargetFormType, FSMList_t NextAction)
{
    static int cnt = 0;
    bool ChangeFinished = false;

    if (FollowManager.GroundOpenmvFramePtr->FormType == TargetFormType)
    {
        cnt++;

        if (cnt > HoldTime)
        {
            cnt = 0;
            FollowManager.ActionList = NextAction;
            ChangeFinished = true;
        }
    }
    else
    {
        cnt = 0;
    }

    return ChangeFinished;
}

void ActionHoldPoint(int8_t Err, int16_t HoldTime, FSMList_t NextAction)
{
    static bool Enter = true;
    static uint16_t CountDown = 0;

    if (Enter)
    {
        CountDown = HoldTime;
        Enter = false;
    }
    else
    {
        CountDown--;
    }

    if (CountDown == 0)
    {
        Enter = true;
        FollowManager.ActionList = NextAction;
    }
}

void UpdateButton()
{
    //判定两个输入是否有效,其实是判断左右两个按键
    volatile static uint8_t input = 0;
    volatile static uint8_t input2 = 0;
    input = P1IN & BIT1;
    input2 = P1IN & BIT4;

    //判断巡线按钮是否按下
    if (input)
    {
    }
    else
    {
        FollowLine = true;
    }

    //判断寻找ApriTag按钮是否按下
    if (input2)
    {
    }
    else
    {
        FollowApriTag = true;
    }

    //判断当前是否被多按
    if (FollowApriTag == false && FollowLine == false)
    {
        return;
    }
    else
    {
        static bool CloseGate = true;

        //动作线进入倒计时状态
        if (CloseGate)
        {
            CloseGate = false;
            FollowManager.ActionList = ActionCountdown;
        }
    }
}

extern float PIDGroup_desired_yaw_pos_tmp;
void HoldYawAngle(float dt)
{
    //更新测量点
    PIDGroup[emPID_FollowSpdYaw].measured = FollowManager.FrontOpenmvFramePtr->CentPoint.x1;
    UpdatePID(FollowManager.ptrPIDInfoY, dt);

    //    PIDGroup_desired_yaw_pos_tmp = -FollowManager.ptrPIDInfoY->out;
    sdk_yaw_little(FollowManager.ptrPIDInfoY->out);
    //    sdk_yaw_little(FollowManager.ptrPIDInfoY->out);
}

float update_yaw_info_in_360()
{
    float angle = 0;

    angle = g_Attitude.yaw;

    if (angle < 0)
    {
        angle += 360;
    }

    return angle;
}

bool is_set_round(float first_angle, float current_angle)
{
    static uint8_t step = 0;
    bool result = false;

    switch (step)
    {
    case 0:
        //waiting
        step = 1;
        break;
    case 1:
        //mark
        step = 2;
        break;
    case 2:
        if (absFloat(current_angle - first_angle) / 2 > 90)
        {
            step = 3;
        }
        break;
    case 3:
        if (absFloat(current_angle - first_angle) / 2 < 5)
        {
            step = 0;
            result = true;
        }
        break;
    default:
        break;
    }

    return result;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无人机巡线(1) 的相关文章

  • freeRTOS 任务切换

    使用PendSV实现任务切换 上下文切换被触发的场合可以是 xff1a 1 执行一个系统调用 2 系统滴答定时器 SysTick 中断 br PendSV中断服务函数 br TaskSelectHighestPrior的两种方法 br br
  • make -j 参数加快编译效率

    对于大型项目 xff0c 在使用cmake控制编译时 xff0c 仅仅执行make指令效率较低 xff0c 使用make j后面跟一个数字 xff0c 比如make j4 make j6 make j14等 含义是 让make最多允许n个编
  • cmake中add_dependencies的基本作用

    假设我们需要生成一个可执行文件 该文件生成需要链接a so b so c so d so四个动态库 正常来讲 我们一把只需要以下两条指令即可 ADD EXECUTABLE span class token punctuation span
  • 命令行给cmake传递参数

    我们期望在编译前将一些信息缓存起来 然后用CMakeLists txt进行构建时 希望可以访问之前缓存给cmake的变量 比如我们希望缓存TARGET CPU 并且他的值为X86 那么我们可以在命令行或者脚本中执行一下操作 cmake DT
  • 在CMakeLists.txt如何执行脚本?execute_process

    execute process span class token punctuation span COMMAND span class token function bash span SCRIPT PATH name sh WORK P
  • C++运算符重载中有些方法为什么需要定义为友元函数

    C 43 43 提供运算符重载主要目的 xff1a 希望对象之间的运算看起来可以和编译器内置类型一样丝滑 xff1b 相当于是告知编译器 xff0c 类对象之间运算应该如何去做处理 通过实现一个复数类 xff0c 来阐述本文章的主题 xff
  • linux网络编程之socket,bind,listen,connect,accept

    socket span class token macro property span class token directive hash span span class token directive keyword include s
  • Linux网络发送和接收内核缓冲区大小的设置

    socket属性 xff1a SO SNDBUF 发送缓冲区 SO SNDBUF Sets or gets the maximum socket send buffer span class token keyword in span by
  • docker查看运行时容器的IP地址

    使用inspect来查看容器的信息 span class token function docker span inspect span class token punctuation span docker name span class
  • python基础梳理(一)

    一 python程序的组成 表达式 xff1a 建立并且处理数据对象且能返回数据对象的引用关系 示例 xff1a 1 43 2 系统会产生1和2俩个对象 xff0c 并且进行处理生产对象3 xff0c 将对象3返回回去 二 核心的数字类型
  • 串级PID结构及参数调整见解

    在设计控制系统中 xff0c 常用的控制算法为PID xff0c 即比例 积分 微分控制器 能够实现对控制对象的物理特性的控制 xff0c 以期达到特定的运行效果 此外由于PID控制器的灵活特性 xff0c 可以与其它控制算法进行灵活的组合
  • freeRTOS 开启关闭调度器、挂起恢复调度器、vTaskStepTick

    1 开启调度器 br vTaskStartScheduler 43 vPortSetupTimerInterrupt 设置systick xff0c 初始化低功耗运行系统补偿时间 br 43 xPortStartScheduler 43 p
  • 通过Flask框架封装Tushare获取的日线股票数据

    概要介绍 概要介绍 xff08 TuShare id 282782 xff09 当我们需要进行量化交易分析 xff0c 或者通过代码进行股票的数据计算 xff0c 研究金融时 xff0c 我们需要获取最基本的股票价格 xff0c 开盘价收盘
  • linux系统安装硬盘分区建议

    笔者使用linux也很长时间了 xff0c 但总有在使用一段时间之后感觉系统分区不是很合理 xff0c 这里就算是给自己总结一下 xff0c 也跟大家一起分享吧 一 常见挂载点的情况说明 一般来说 xff0c 在linux系统中都有最少两个
  • Python3.4简单爬虫实现之抓取糗事百科段子

    网上的python教程大都是2 X版本的 xff0c python2 X和python3 X相比较改动比较大 xff0c 好多库的用法不太一样 xff0c 我安装的是3 4 1 xff0c 就用3 4 1实现一下网页内容抓取 首先是库 xf
  • 关于stm32中串口重定向问题详解(找个时间好好理解下)

    usart这部分代码我也是从网上copy出来的 xff0c 一下是作者的解释 xff1a 简单地说 xff1a 想在mdk 中用printf xff0c 需要同时重定义fputc函数和避免使用semihosting 半主机模式 xff09
  • http解析库http-parser

    一 http parser简介 1 简介 http parser是一个用C编写的HTTP消息解析器 xff0c 可以解析请求和响应 xff0c 被设计用于高性能HTTP应用程序 它不会进行任何系统调用及内存分配 xff0c 它不会缓冲数据
  • centos系统重置root密码,忘记密码修改

    1 开机按下Ecs键 xff0c 进入如下界面 2 根据需要选择系统内核版本并按e键 3 光标移动到 linux 16 开头的行 xff0c 找到 ro 改为 rw init 61 sysroot bin sh xff1b 4 按 Ctrl
  • summary1 如何在Python中创建基本的ROS节点[AI]

    本课程结束时 xff0c 您将能够 xff1a 1 在模拟中 xff0c 使用ROS控制TurtleBot3机器人 2 使用roslaunch和rosrun启动ROS应用程序 3 使用关键ROS命令行工具询问正在运行的ROS应用程序 4 创

随机推荐

  • switch case语句用法

    一般情况下 xff0c 判断语句常用的有if else xff0c 三目运算符 xff0c 还有switch case等 xff0c 根据不同需求使用其判断语句 下面以简单示例展示 xff1a 在输入框中输入数字 xff0c 判断其星期几
  • 四轴飞行器基础

    原文知识来自果壳网 四轴飞行器基础篇 xff0c 进行一些适量增删 基本原理与名词解释 1 遥控器篇 通道 通道就是可以遥控器控制的动作路数 xff0c 比如遥控器只能控制四轴上下飞 xff0c 那么就是1个通道 但四轴在控制过程中需要控制
  • OPENWRT,爱快等软路由推荐

    这种用于路由器的开源固件 操作系统可以让它获得大多数路由器所不具备的功能 xff0c 甚至可以把一台旧PC变成强大的路由器或防火墙设备 软路由提供的一些特性和功能包括带宽监控 VLAN支持 高级无线设置 VPN集成 高级安全等等 在这篇文章
  • freeRTOS 时间管理

    1 相对时间延时 br vTaskDelay gt prvAddCurrentTaskToDelayedList 函数分析之后 xff0c 有步骤解析 br 为什么使用两个延时列表 xff1f br br br 2 绝对时间延时 br Pr
  • 美团笔试题_20220409

    前言 笔试一共五道编程题 xff08 四 43 一 xff09 xff0c 一为专项编程题 xff0c 估计不同岗位有题目不一样 xff0c 使用的是赛码网 xff0c 允许跳出界面使用自己的IDE 在此感谢筱羊冰冰提供的部分题目及题解 题
  • 最简单的socket 与物流网的传感器交换数据

    做个笔记 最简单的socket 要与物流网的传感器交换数据 登录分为用户登录 与 设备登录 1 用户登录 xff08 SSLSOCKET xff09 M login ID xx1 K xx2 n json格式 最简单的SSLSocket 基
  • 如何开发出成功的硬件产品,一个产品由概念的产生到产品的落地量产又需要经历哪些流程呢?

    对于一个硬件产品而言 xff0c 大批量的生产交付才能实现其最大的商业价值 然而 xff0c 不同于软件产品的复制升级 xff0c 硬件产品大批量生产背后所涉及的生产制造 工艺测试 品质功能 可靠性 成本等等一系列问题 xff0c 都是一个
  • 进程切换与线程切换的区别

    一 虚拟内存知识复习 虚拟内存是操作系统为每个进程提供的一种抽象 xff0c 每个进程都有属于自己的 私有的 地址连续的虚拟内存 xff0c 当然我们知道最终进程的数据及代码必然要放到物理内存上 xff0c 那么必须有某种机制能记住虚拟地址
  • eclipse-tomcat解决java.lang.OutOfMemoryError: PermGen space

    在eclipse中使用tomcat启动项目的时候 遇到问题 xff0c 报错 xff1a java lang OutOfMemoryError PermGen space 原因很简单 内存溢出 xff0c 解决方法 1 双击红色部分 2 单
  • JavaWeb项目中加入redis缓存

    关于redis缓存的优缺点不再多做结束 xff0c 请自行上网查询 1 下载 xff1a windows版本资源我已经上传 xff0c 链接 xff1a http download csdn net detail kkkder 963718
  • java 格式化时间

    public static void main String args System out println System currentTimeMillis SimpleDateFormat formatter 61 new Simple
  • linux docker删除镜像

    springcloud参考指南下载 xff1a http download csdn net download kkkder 10035750 之前的没有接触的docker xff0c 找了些文档 xff0c 按部就班的在linux下安装部
  • springboot activiti工作流简单示例

    最近一直研究springboot xff0c 根据工作需求 xff0c 工作流需要作为一个单独的微服务工程来提供给其他服务调用 xff0c 现在简单的写下工作流 xff08 使用的activiti xff09 微服务的搭建与简单使用 jdk
  • Error parsing lifecycle processing instructions pom.xml /xxxxx Maven Project Build Life

    本机是windows7 64bit xff0c eclipse版本信息 xff1a Eclipse Java EE IDE for Web Developers Version Neon 3 Release 4 6 3 Build id 2
  • freeRTOS 信号量:二值 计数 互斥 递归互斥

    用于信号量的队列 xff0c 都是只有队列数据结构的空间 xff0c 没有队列项存储空间的队列 二值 计数 互斥 递归互斥 xff0c 创建完成之后的内存状态 xff1a 转自 http blog csdn net zhzht1986101
  • Mapped Statements collection does not contain value for xxx

    说个同事出现的问题 xff1a Mapped Statements collection does not contain value for xxx 当时第一反应 xff0c 就是sql文件中没有定义id为 xxx xff0c 查看sql
  • CentOS mysql 安装

    1 因个人需要 安装了JDK https blog csdn net kkkder article details 78349419 2 下载https dev mysql com downloads mysql 5 7 html down
  • Spring AOP 日志记录

    package com config import java util Date AOP 添加访问日志 import org aspectj lang JoinPoint import org aspectj lang annotation
  • linux redis安装

    1 CentOS7 联网 2 进入redis官网 https redis io download 3 官网有详细教程 在执行make命令时 xff0c 报错 xff1a echo 34 34 gt make ldflags MAKE hir
  • 无人机巡线(1)

    本程序完成2020年电赛试题主要内容 如果用户认为已经掌握该文件使用方法 xff0c 请删除此文件 xff0c 然后添加FollowLine c文件 1 拿到了绿色的数据 xff1b 2 include 34 FollowLine h 34