/* 自定义的数学运算。 */ #include "user_math.h" #include "math.h" #include /** * \brief 映射函数 * * \param x 输入值 * \param in_min 输入最小值 * \param in_min 输入最大值 * \param in_min 输出最小值 * \param in_min 输出最大值 * * \return 映射完成后的数 */ int map_int(int x, int in_min, int in_max, int out_min, int out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } fp32 map_fp32(fp32 x, fp32 in_min, fp32 in_max, fp32 out_min, fp32 out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } int Setint_Deadzone(int value,int deadzone) { if(value>=-deadzone&&value<=deadzone) { value =0; } return 1; } float abs_float_double(float a,float b){ if((a-b)<0){return (b-a);} else if((a>b)>0){return (a-b);} else return 0; } float abs_float_single (float a){ if(a<0) return -a; else if(a>0) return a; else return 0; } // 归一化角度到 [0,2PI] float _normalizeAngle(float angle) { float a = fmod(angle, 2*M_PI); //取余运算可以用于归一化,列出特殊值例子算便知 return a >= 0 ? a : (a + 2*M_PI); } //归一化角度到 [0,360] float _normalizeTo360(float angle) { // 使用 fmod 函数取 angle 除以 360 的余数 float a = fmod(angle, 360.0f); // 如果余数小于 0,则加上 360 再返回 return a < 0 ? (a + 360.0f) : a; } //角度量纲的转换 fp32 AngleChange(Angle_e hopetype,fp32 angle) { fp32 hope_angle; if(hopetype==DEGREE) { hope_angle = angle*180/M_PI; //弧度制转角度制 } else if(hopetype ==RADIAN) { hope_angle = angle*M_PI/180; //角度值转弧度制 } return hope_angle; } //获取角度的函数 /* param in type:获取角度的类型 RELATIVE ABSOLUTE abs_angle:绝对角度的获取 注意是指针类型 zero_point:零点值 用于计算相对角度 param out final_angle: 用于输出最后期望的角度值 */ fp32 AngleCalc(AngleType_e type, fp32 abs_angle,fp32 zero_point) { fp32 final_angle=0; if(type==RELATIVE) { if(abs_angle - zero_point >=0.0f) { final_angle = abs_angle - zero_point; } else final_angle = M_2PI +(abs_angle -zero_point); } else if(type ==ABSOLUTE) { final_angle = abs_angle; } return final_angle; } // 函数:计算最短路径需要转动的角度 float calculate_rotation(float current_angle, float target_angle) { float diff = target_angle - current_angle; // 将差值调整到-180到180之间 if (diff > 180.0f) { diff -= 360.0f; } else if (diff < -180.0f) { diff += 360.0f; } return diff; } //相加两个极坐标向量并返回结果 PolarCoordinate_t addPolarVectors(PolarCoordinate_t v1, PolarCoordinate_t v2) { // 将极坐标转换为直角坐标 double x1, y1, x2, y2; x1 = v1.r * cos(v1.theta); y1 = v1.r * sin(v1.theta); x2 = v2.r * cos(v2.theta); y2 = v2.r * sin(v2.theta); // 直角坐标相加 double x_sum = x1 + x2; double y_sum = y1 + y2; // 将直角坐标结果转换回极坐标 PolarCoordinate_t sum; sum.r = sqrt(x_sum * x_sum + y_sum * y_sum); sum.theta = atan2(y_sum, x_sum); return sum; } //函数用于将直角坐标转换为极坐标 PolarCoordinate_t cartesianToPolar(fp32 x, fp32 y) { PolarCoordinate_t polar; // 计算极径 polar.r = sqrt(x * x + y * y); // 计算极角 if (x == 0) { if (y > 0) { polar.theta = M_PI / 2.0f; } else if (y < 0) { polar.theta = -M_PI / 2.0f; } else { polar.theta = 0; // 任何角度都可以表示为0 } } else { polar.theta = atan2(y, x); } return polar; } //循环限幅 fp32 loop_fp32_constrain(fp32 Input, fp32 minValue, fp32 maxValue) { if (maxValue < minValue) { return Input; } if (Input > maxValue) { fp32 len = maxValue - minValue; while (Input > maxValue) { Input -= len; } } else if (Input < minValue) { fp32 len = maxValue - minValue; while (Input < minValue) { Input += len; } } return Input; } //限幅 void abs_limit_fp(fp32 *num, fp32 Limit) { if (*num > Limit) { *num = Limit; } else if (*num < -Limit) { *num = -Limit; } } /* 移动向量 */ MoveVector_t *mv; inline float InvSqrt(float x) { #if 0 /* Fast inverse square-root */ /* See: http://en.wikipedia.org/wiki/Fast_inverse_square_root */ float halfx = 0.5f * x; float y = x; long i = *(long*)&y; i = 0x5f3759df - (i>>1); y = *(float*)&i; y = y * (1.5f - (halfx * y * y)); y = y * (1.5f - (halfx * y * y)); return y; #else return 1.0f / sqrtf(x); #endif } inline float AbsClip(float in, float limit) { return (in < -limit) ? -limit : ((in > limit) ? limit : in); } inline void Clip(float *origin, float min, float max) { if (*origin > max) *origin = max; if (*origin < min) *origin = min; } inline float Sign(float in) { return (in > 0) ? 1.0f : 0.0f; } /** * \brief 将运动向量置零 * * \param mv 被操作的值 */ inline void ResetMoveVector(MoveVector_t *mv) { memset(mv, 0, sizeof(*mv)); } /** * \brief 计算循环值的误差,用于没有负数值,并在一定范围内变化的值 * 例如编码器:相差1.5PI其实等于相差-0.5PI * * \param sp 被操作的值 * \param fb 变化量 * \param range 被操作的值变化范围,正数时起效 * * \return 函数运行结果 */ inline float CircleError(float sp, float fb, float range) { float error = sp - fb; if (range > 0.0f) { float half_range = range / 2.0f; if (error > half_range) error -= range; else if (error < -half_range) error += range; } return error; } /** * \brief 循环加法,用于没有负数值,并在一定范围内变化的值 * 例如编码器,在0-2PI内变化,1.5PI + 1.5PI = 1PI * * \param origin 被操作的值 * \param delta 变化量 * \param range 被操作的值变化范围,正数时起效 */ inline void CircleAdd(float *origin, float delta, float range) { float out = *origin + delta; if (range > 0.0f) { if (out >= range) out -= range; else if (out < 0.0f) out += range; } *origin = out; } /** * @brief 循环值取反 * * @param origin 被操作的值 */ inline void CircleReverse(float *origin) { *origin = -(*origin) + M_2PI; } /// @brief /// @param arr 数组 /// @param n 元素数 /// @return 平均值 uint8_t average(uint8_t arr[], uint8_t n) { int sum = 0; for (int i = 0; i < n; i++) { sum += arr[i]; } return (float) sum / n; }