STM32平衡車開發實戰教程:從零基礎到項目精通

STM32平衡車開發實戰教程:從零基礎到項目精通

一、項目概述與基本原理

1.1 平衡車工作原理

平衡車是一種基于倒立擺原理的兩輪自平衡小車,其核心控制原理類似于人類保持平衡的過程。當人站立不穩時,會通過腿部肌肉的快速調整來維持平衡。平衡車同樣通過傳感器檢測車身傾斜角度,利用電機驅動實現動態平衡。

核心控制原理

  1. 姿態感知:通過MPU6050六軸傳感器(三軸加速度計+三軸陀螺儀)實時檢測小車的傾斜角度和角速度
  2. 控制算法:使用PID算法計算電機控制量,其中:
    • 比例項§快速響應角度偏差
    • 積分項(I)消除靜態誤差
    • 微分項(D)抑制振蕩
  3. 執行機構:電機根據控制量調整轉速,保持平衡

1.2 系統組成與功能

基本功能模塊

  • 主控制器:STM32F103C8T6(性價比高,資源豐富)
  • 姿態傳感器:MPU6050(檢測傾角)
  • 電機驅動:TB6612(高效驅動電機)
  • 編碼器:測量電機轉速(反饋控制)
  • 電源管理:鋰電池供電系統
  • 通信模塊:藍牙/WiFi(無線控制)
  • 顯示模塊:OLED(狀態顯示)

進階功能擴展

  • 超聲波避障
  • 紅外循跡
  • 手機APP遙控
  • 語音控制

二、硬件設計與組裝

2.1 硬件選型指南

部件推薦型號關鍵參數注意事項
主控芯片STM32F103C8T6Cortex-M3內核,72MHz主頻,64KB Flash確保有足夠定時器資源
姿態傳感器MPU6050±2g加速度,±2000°/s陀螺儀注意安裝方向與位置
電機MG315帶編碼器減速比1:30,編碼器11線需配對使用
電機驅動TB6612FNG雙通道,1.2A連續電流比L298N效率高
電源18650鋰電池×312V供電需配保護板
藍牙模塊HC-06藍牙4.0,串口通信注意主從模式
顯示模塊0.96寸OLEDI2C接口,128×64分辨率可選SPI接口版本

2.2 詳細電路連接

STM32最小系統連接

  1. 8MHz晶振連接OSC_IN/OSC_OUT
  2. 復位電路連接NRST
  3. Boot0通過10K電阻接地
  4. 3.3V穩壓電路(AMS1117-3.3)

MPU6050連接

  • VCC → 3.3V
  • GND → GND
  • SCL → PB6
  • SDA → PB7
  • INT → PA0(外部中斷)

TB6612電機驅動連接

  • PWMA → PA8(TIM1_CH1)
  • PWMB → PA11(TIM1_CH4)
  • AIN1 → PC13, AIN2 → PC14
  • BIN1 → PC15, BIN2 → PD2
  • STBY → 3.3V(常使能)

編碼器連接

  • 左編碼器A相 → PA0(TIM2_CH1)
  • 左編碼器B相 → PA1(TIM2_CH2)
  • 右編碼器A相 → PB6(TIM4_CH1)
  • 右編碼器B相 → PB7(TIM4_CH2)

電源系統設計

  1. 主電源:3節18650鋰電池(12V)
  2. 5V降壓:MP1584EN模塊(為傳感器供電)
  3. 3.3V穩壓:AMS1117-3.3(為MCU和傳感器供電)

2.3 PCB設計與制作

設計要點

  1. 電機驅動部分走線加寬(至少1mm)
  2. 模擬部分(傳感器)與數字部分分開布局
  3. 添加電源濾波電容(10uF電解+0.1uF陶瓷)
  4. MPU6050盡量靠近MCU放置

常見問題解決

  • 電機干擾導致復位:加強電源濾波,縮短電機線長度
  • 傳感器數據跳動:確保I2C線上拉電阻(4.7K)正確連接
  • 電機不轉:檢查STBY引腳電平,確認PWM信號正常

三、軟件架構與核心算法

3.1 系統軟件架構

分層設計

  1. 硬件抽象層(HAL)

    • 傳感器驅動(MPU6050)
    • 電機驅動(TB6612)
    • 編碼器接口
    • 通信接口(藍牙/串口)
  2. 算法層

    • 姿態解算(互補濾波/卡爾曼濾波)
    • PID控制算法
    • 數據濾波處理
  3. 應用層

    • 任務調度
    • 人機交互(按鍵/顯示)
    • 遙控處理
  4. 通信層

    • 藍牙協議處理
    • 串口調試接口

3.2 姿態解算算法

互補濾波實現

// 互補濾波函數
float ComplementaryFilter(float accelAngle, float gyroRate, float dt, float alpha) {static float angle = 0;angle = alpha * (angle + gyroRate * dt) + (1 - alpha) * accelAngle;return angle;
}// 調用示例
void IMU_Update() {// 讀取傳感器原始數據MPU6050_ReadData(&accelX, &accelY, &accelZ, &gyroX, &gyroY, &gyroZ);// 計算加速度角度float accelAngle = atan2(accelY, accelZ) * 180.0 / PI;// 獲取陀螺儀角速度(轉換為度/秒)float gyroRate = gyroX / 16.4f;// 互補濾波float dt = 0.005f; // 5ms采樣周期float alpha = 0.98f; // 濾波系數currentAngle = ComplementaryFilter(accelAngle, gyroRate, dt, alpha);
}

卡爾曼濾波實現

typedef struct {float Q_angle; // 過程噪聲協方差float Q_bias;  // 過程噪聲協方差float R_measure; // 測量噪聲協方差float angle;  // 計算得到的最優角度float bias;   // 陀螺儀偏置float P[2][2]; // 誤差協方差矩陣
} KalmanFilter;float Kalman_Update(KalmanFilter *kf, float newAngle, float newRate, float dt) {// 預測步驟kf->angle += dt * (newRate - kf->bias);kf->P[0][0] += dt * (dt*kf->P[1][1] - kf->P[0][1] - kf->P[1][0] + kf->Q_angle);kf->P[0][1] -= dt * kf->P[1][1];kf->P[1][0] -= dt * kf->P[1][1];kf->P[1][1] += kf->Q_bias * dt;// 更新步驟float y = newAngle - kf->angle;float S = kf->P[0][0] + kf->R_measure;float K[2];K[0] = kf->P[0][0] / S;K[1] = kf->P[1][0] / S;// 更新估計值kf->angle += K[0] * y;kf->bias += K[1] * y;// 更新協方差矩陣float P00_temp = kf->P[0][0];float P01_temp = kf->P[0][1];kf->P[0][0] -= K[0] * P00_temp;kf->P[0][1] -= K[0] * P01_temp;kf->P[1][0] -= K[1] * P00_temp;kf->P[1][1] -= K[1] * P01_temp;return kf->angle;
}

3.3 PID控制算法

串級PID實現

typedef struct {float Kp, Ki, Kd;float integral;float prevError;float integralLimit;
} PID_Controller;float PID_Update(PID_Controller *pid, float error, float dt) {// 比例項float proportional = pid->Kp * error;// 積分項pid->integral += error * dt;// 積分限幅if(pid->integral > pid->integralLimit) pid->integral = pid->integralLimit;else if(pid->integral < -pid->integralLimit) pid->integral = -pid->integralLimit;float integral = pid->Ki * pid->integral;// 微分項float derivative = pid->Kd * (error - pid->prevError) / dt;pid->prevError = error;return proportional + integral + derivative;
}// 直立環PD控制
float Balance_PID(float angle, float targetAngle, float gyroRate) {static PID_Controller pid = {20.0f, 0.0f, 0.5f, 0, 0, 1000};float error = angle - targetAngle;return PID_Update(&pid, error, 0.005f) + pid.Kd * gyroRate;
}// 速度環PI控制
float Velocity_PID(int encoderLeft, int encoderRight) {static PID_Controller pid = {0.3f, 0.001f, 0.0f, 0, 0, 10000};int speed = (encoderLeft + encoderRight) / 2; // 平均速度return PID_Update(&pid, -speed, 0.005f); // 目標速度為0
}

四、系統實現與調試

4.1 主程序框架

int main(void) {// 系統初始化HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_TIM1_Init(); // PWM定時器MX_TIM2_Init(); // 編碼器1MX_TIM4_Init(); // 編碼器2MX_I2C1_Init(); // MPU6050MX_USART1_UART_Init(); // 調試串口// 外設初始化MPU6050_Init();Motor_Init();Encoder_Init();OLED_Init();Bluetooth_Init();// 主循環while (1) {// 1. 讀取傳感器數據MPU6050_ReadData(&imuData);// 2. 姿態解算currentAngle = ComplementaryFilter(atan2(imuData.Accel_Y, imuData.Accel_Z) * RAD_TO_DEG,imuData.Gyro_X,0.005f, // 5ms0.98f);// 3. 讀取編碼器速度int speedLeft = Read_Encoder(TIM_ENCODER_LEFT);int speedRight = Read_Encoder(TIM_ENCODER_RIGHT);// 4. PID控制計算float balanceOut = Balance_PID(currentAngle, TARGET_ANGLE, imuData.Gyro_X);float speedOut = Velocity_PID(speedLeft, speedRight);// 5. 綜合控制輸出int motorOut = balanceOut + speedOut;// 6. 電機控制Motor_SetPWM(MOTOR_LEFT, motorOut);Motor_SetPWM(MOTOR_RIGHT, motorOut);// 7. 狀態顯示與通信if(HAL_GetTick() - lastDisplayTime >= 100) { // 100ms更新一次顯示OLED_ShowAngle(currentAngle);Bluetooth_SendData(currentAngle);lastDisplayTime = HAL_GetTick();}HAL_Delay(5); // 5ms控制周期}
}

4.2 關鍵模塊實現

MPU6050初始化與數據讀取

void MPU6050_Init(void) {// 復位設備MPU6050_WriteByte(MPU6050_RA_PWR_MGMT_1, 0x80);HAL_Delay(100);// 喚醒設備,選擇時鐘源MPU6050_WriteByte(MPU6050_RA_PWR_MGMT_1, 0x01);// 設置陀螺儀量程 ±2000°/sMPU6050_WriteByte(MPU6050_RA_GYRO_CONFIG, 0x18);// 設置加速度計量程 ±2gMPU6050_WriteByte(MPU6050_RA_ACCEL_CONFIG, 0x00);// 設置低通濾波器帶寬 44HzMPU6050_WriteByte(MPU6050_RA_CONFIG, 0x03);// 設置采樣率 1kHzMPU6050_WriteByte(MPU6050_RA_SMPLRT_DIV, 0x00);
}void MPU6050_ReadData(MPU6050_Data *data) {uint8_t buf[14];MPU6050_ReadBytes(MPU6050_RA_ACCEL_XOUT_H, 14, buf);data->Accel_X = (int16_t)(buf[0] << 8 | buf[1]);data->Accel_Y = (int16_t)(buf[2] << 8 | buf[3]);data->Accel_Z = (int16_t)(buf[4] << 8 | buf[5]);data->Temp = (int16_t)(buf[6] << 8 | buf[7]);data->Gyro_X = (int16_t)(buf[8] << 8 | buf[9]);data->Gyro_Y = (int16_t)(buf[10] << 8 | buf[11]);data->Gyro_Z = (int16_t)(buf[12] << 8 | buf[13]);
}

編碼器接口配置

void Encoder_Init(void) {TIM_Encoder_InitTypeDef sConfig = {0};TIM_MasterConfigTypeDef sMasterConfig = {0};// 編碼器1配置(TIM2)htim2.Instance = TIM2;htim2.Init.Prescaler = 0;htim2.Init.CounterMode = TIM_COUNTERMODE_UP;htim2.Init.Period = 65535;htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;sConfig.EncoderMode = TIM_ENCODERMODE_TI12;sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;sConfig.IC1Prescaler = TIM_ICPSC_DIV1;sConfig.IC1Filter = 0;sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;sConfig.IC2Prescaler = TIM_ICPSC_DIV1;sConfig.IC2Filter = 0;HAL_TIM_Encoder_Init(&htim2, &sConfig);sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig);HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL);// 編碼器2配置(TIM4)類似...
}

4.3 PID參數整定方法

調參步驟

  1. 確定機械中值

    • 將小車放在地面上,尋找能夠自然平衡的角度
    • 記錄這個角度作為TARGET_ANGLE(通常在-3°到3°之間)
  2. 直立環調參

    • 先調Kp(比例項):
      • 從較小值開始(如10)
      • 逐漸增大直到小車出現低頻振蕩
      • 典型值范圍:20-50
    • 再調Kd(微分項):
      • 從0.1開始
      • 逐漸增大抑制振蕩
      • 過大則會出現高頻抖動
      • 典型值范圍:0.3-0.8
  3. 速度環調參

    • 先調Kp:
      • 從0.1開始
      • 增大使小車能抵抗外力
      • 過大則會出現前后擺動
      • 典型值范圍:0.2-0.5
    • Ki與Kp保持比例關系(Ki ≈ Kp/200):
      • 消除靜態誤差
      • 過大則積分飽和
  4. 轉向環調參(可選)

    • 使用單獨的Kp控制
    • 根據轉向靈敏度調整
    • 典型值范圍:0.1-1.0

調試技巧

  • 使用藍牙或串口實時調整參數
  • 記錄數據并分析響應曲線
  • 采用"試湊法"結合理論分析
  • 先調內環再調外環

五、進階優化與功能擴展

5.1 系統優化策略

實時性優化

  1. 使用定時器中斷確保控制周期精確

    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {if(htim->Instance == TIM6) { // 5ms定時器// 執行控制算法Control_Task();}
    }
    
  2. 優化傳感器數據讀取速度

    • 使用DMA傳輸減少CPU開銷
    • 提高I2C時鐘頻率(400kHz)
  3. 關鍵代碼使用匯編優化

    • PID計算等關鍵算法

穩定性優化

  1. 增加軟件看門狗
  2. 異常狀態檢測與保護
    • 角度過大時切斷電機
    • 通信異常處理

5.2 功能擴展實現

藍牙遙控功能

void Bluetooth_Process(void) {if(UART_Receive(&huart3, &bluetoothData, 1) == HAL_OK) {switch(bluetoothData) {case 'F': targetSpeed += 10; break; // 前進case 'B': targetSpeed -= 10; break; // 后退case 'L': turnOffset = -5; break;   // 左轉case 'R': turnOffset = 5; break;    // 右轉case 'S': targetSpeed = 0; break;   // 停止}}
}

超聲波避障功能

float Ultrasonic_GetDistance(void) {// 觸發信號HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_SET);HAL_Delay(0.01);HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_RESET);// 等待回波while(HAL_GPIO_ReadPin(ECHO_GPIO_Port, ECHO_Pin) == GPIO_PIN_RESET);uint32_t start = HAL_GetTick();while(HAL_GPIO_ReadPin(ECHO_GPIO_Port, ECHO_Pin) == GPIO_PIN_SET);uint32_t end = HAL_GetTick();// 計算距離(cm)return (end - start) * 0.034 / 2;
}

數據記錄與分析

  1. 使用SD卡模塊記錄運行數據
  2. 通過無線模塊上傳到云端
  3. 使用MATLAB/Python分析數據

六、項目總結與進階學習

6.1 常見問題解決

問題1:小車無法保持平衡

  • 檢查傳感器數據是否正確
  • 確認PID參數極性是否正確
  • 檢查電機轉向是否正確

問題2:小車出現高頻振蕩

  • 減小微分項Kd
  • 檢查機械結構是否牢固
  • 增加傳感器數據濾波

問題3:小車向一邊偏移

  • 檢查機械結構對稱性
  • 校準傳感器
  • 調整機械中值

6.2 學習資源推薦

開源項目參考

  1. 平衡小車之家開源項目
  2. Cleanflight/Betaflight飛控代碼
  3. 小馬哥四軸開源項目

推薦書籍

  • 《STM32庫開發實戰指南》
  • 《自動控制原理》
  • 《嵌入式實時操作系統》

進階方向

  1. 改用RTOS實現多任務
  2. 加入機器學習算法
  3. 實現集群控制
  4. 開發手機APP控制界面

6.3 項目展示與分享

博客撰寫要點

  1. 項目背景與意義
  2. 系統設計與實現
  3. 關鍵技術難點與解決方案
  4. 效果展示(視頻/圖片)
  5. 經驗總結與未來改進

面試項目介紹要點

  • 突出技術難點和解決方案
  • 展示對系統原理的深入理解
  • 說明個人貢獻和收獲
  • 準備技術細節的深入討論

通過本教程,您已經掌握了STM32平衡車從硬件設計到軟件實現的完整開發流程。建議按照步驟實際動手實踐,在實踐中深化理解。平衡車項目是學習嵌入式系統和控制算法的絕佳平臺,希望您能在此基礎上不斷探索和創新!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/901527.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/901527.shtml
英文地址,請注明出處:http://en.pswp.cn/news/901527.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C#設計模式-狀態模式

狀態模式案例解析&#xff1a;三態循環燈的實現 案例概述 本案例使用 狀態模式&#xff08;State Pattern&#xff09; 實現了一個 三態循環燈 的功能。每點擊一次按鈕&#xff0c;燈的狀態會按順序切換&#xff08;狀態1 → 狀態2 → 狀態3 → 狀態1...&#xff09;&#xff…

Mac系統升級node.js版本和npm版本并安裝pnpm

1.升級node.js版本 第一步&#xff1a;查詢當前node.js版本 node -v第二步&#xff1a;清除node.js的緩存 sudo npm cache clean -f第三步&#xff1a;驗證緩存是否清空 npm cache verify第四步&#xff1a;安裝n工具&#xff0c;n工具是專門用于管理node.js版本的工具 su…

[net 5] udp_dict_server 基于udp的簡單字典翻譯(服務器與業務相分離)

目錄 1. 功能了解 1.1. 啥是 dic_server? 1.2. dic_server 的小目標 2. 基本框架 2.1. 基本文件框架 2.2. 業務與服務器解耦 -> 回調函數 3. 字典 3.1. 字典配置文件 3.2. 構建字典類 3.2.1. 字典類的基本成員 3.2.2. 字典類構造 3.2.2.1. 構造 3.2.2.2. 信息加…

七種驅動器綜合對比——《器件手冊--驅動器》

九、驅動器 名稱 功能與作用 工作原理 優勢 應用 隔離式柵極驅動器 隔離式柵極驅動器用于控制功率晶體管&#xff08;如MOSFET、IGBT、SiC或GaN等&#xff09;的開關&#xff0c;其核心功能是將控制信號從低壓側傳輸到高壓側的功率器件柵極&#xff0c;同時在輸入和輸出之…

EM儲能網關ZWS智慧儲能云應用(8) — 電站差異化支持

面對不同項目、種類繁多的儲能產品&#xff0c;如何在儲能云平臺上進行電站差異化支持尤為關鍵&#xff0c;ZWS智慧儲能云從多方面支持儲能電站差異化。 簡介 隨著行業發展&#xff0c;市場“內卷”之下&#xff0c;各大儲能企業推陳出新的速度加快。面對不同項目、種類繁多…

圖像預處理-色彩空間補充,灰度化與二值化

一.圖像色彩空間轉換 1.1 HSV顏色空間 HSV顏色空間使用色調&#xff08;Hue&#xff09;、飽和度&#xff08;Saturation&#xff09;和亮度&#xff08;Value&#xff09;三個參數來表示顏色 一般對顏色空間的圖像進行有效處理都是在HSV空間進行的&#xff0c;然后對于基本…

Midnight Flag CTF 2025

周末還是三個比賽&#xff0c;可惜不好弄。不是遠端連不上就是遠端打不開。再有就是太難了。 Crypto ABC 這個題還是不算難的。給了兩個30位數的平方和&#xff0c;并且pu1*baser0,qu2*baser1其中r 都很小&#xff0c;可以copper。 只是sage里的two_squres不管用&#xff0…

深度學習--激活函數

激活函數通過計算加權和并加上偏置來確定神經元是否應該倍激活&#xff0c;它們將輸入信號轉換為輸出的可微運算。大多數激活函數都是非線性的&#xff0c;由于激活函數是深度學習的基礎&#xff0c;下面簡要介紹一些常見的激活函數。 1 RelU函數 最受歡迎的激活函數是修正線性…

深入解析 OrdinalEncoder 與 OneHotEncoder:核心區別與實戰應用

標題&#xff1a;深入解析 OrdinalEncoder 與 OneHotEncoder&#xff1a;核心區別與實戰應用 摘要&#xff1a; 本文詳細探討了機器學習中類別特征編碼的兩種核心方法——OrdinalEncoder 和 OneHotEncoder。通過對比兩者的功能、特點、適用場景及代碼實現&#xff0c;幫助讀者…

CTF web入門之命令執行 完整版

web29 文件名過濾 由于flag被過濾,需要進行文件名繞過,有以下幾種方法: 1.通配符繞過 fla?.* 2.反斜杠繞過 fl\ag.php 3.雙引號繞過 fl’‘ag’.php 還有特殊變量$1、內聯執行等 此外 讀取文件利用cat函數,輸出利用system、passthru 、echo echo `nl flag.php`; ec…

【Linux實踐系列】:用c/c++制作一個簡易的進程池

&#x1f525; 本文專欄&#xff1a;Linux Linux實踐項目 &#x1f338;作者主頁&#xff1a;努力努力再努力wz &#x1f4aa; 今日博客勵志語錄&#xff1a; 人生沒有標準答案&#xff0c;你的錯題本也能寫成傳奇。 ★★★ 本文前置知識&#xff1a; 匿名管道 1.前置知識回顧…

2.2 函數返回值

1.回顧def def sum(x,y): return xy res sum(10,20) #調用函數 print(res) 2.函數的三個重要屬性 -函數的類型&#xff1a;function -函數的ID&#xff1a;16進制的整數數值 -函數的值&#xff1a;封裝在函數中的數據和代碼 # - 函數是一塊內存空間&#xff0c;通過…

【3GPP核心網】【5G】精講5G網絡語音業務系統架構

1. 歡迎大家訂閱和關注,精講3GPP通信協議(2G/3G/4G/5G/IMS)知識點,專欄會持續更新中.....敬請期待! 目錄 1. 音視頻業務 2. 消息類業務 SMS over IMS SMS over NAS 3. 互聯互通架構 3.1 音視頻業務互通場景 3.2 5G 用戶與 5G 用戶互通 3.3 5G 用戶與 4G 用戶的互通…

系統環境變量有什么實際作用,為什么要配置它

系統環境變量有什么實際作用,為什么要配置它 系統環境變量具有以下重要實際作用: 指定程序路徑:操作系統通過環境變量來知曉可執行文件、庫文件等的存儲位置例如,當你在命令提示符或終端中輸入一個命令時,系統會根據環境變量PATH中指定的路徑去查找對應的可執行文件。如果…

qt/C++面試題自用學習(更新中)

最近在找工作…面試中遇到了的問題總以為自己會但回答的時候磕磕巴巴&#xff0c;覺得還是要總結一下&#xff1a; vector和list的區別 vector list 底層數據結構 基于動態數組實現&#xff0c;元素在內存中連續存儲 基于雙向鏈表實現&#xff0c;元素在內存中非連續存儲&…

Day09【基于Tripletloss實現的簡單意圖識別對話系統】

基于Tripletloss實現的表示型文本匹配 目標數據準備參數配置數據處理Triplet Loss目標Triplet Loss計算公式公式說明 模型構建網絡結構設計網絡訓練目標損失函數設計 主程序推理預測類初始化加載問答知識庫文本向量化知識庫查詢主程序main測試測試效果 參考博客 目標 在此之前…

說說什么是冪等性?

大家好&#xff0c;我是鋒哥。今天分享關于【說說什么是冪等性&#xff1f;】面試題。希望對大家有幫助&#xff1b; 說說什么是冪等性&#xff1f; 1000道 互聯網大廠Java工程師 精選面試題-Java資源分享網 冪等性&#xff08;Idempotence&#xff09; 是指在某些操作或請求…

【自相關】全局 Moran’s I 指數

自相關&#xff08;Autocorrelation&#xff09;&#xff0c;也稱為序列相關性&#xff0c;指的是同一變量在不同時間或空間點的值之間的關系。簡而言之&#xff0c;自相關就是一個變量與自身在不同位置或時間點的相關性 自相關&#xff1a;針對同一屬性之間進行分析相關性 本…

【C#】Html轉Pdf,Spire和iTextSharp結合,.net framework 4.8

&#x1f339;歡迎來到《小5講堂》&#x1f339; &#x1f339;這是《C#》系列文章&#xff0c;每篇文章將以博主理解的角度展開講解。&#x1f339; &#x1f339;溫馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不對之處望指正&#xff01;&#…