“华数杯”数学竞赛A题深度解析与代码分享:2024年赛题全攻略

机器臂关节角路径的优化设计

问题一


代码

  • Matlab
  • clc
    clear
    % 参数定义
    a = [0, 300, 1200, 300, 0, 0];
    alpha = [0, -90, 0, -90, -90, -90];
    d = [600, 0, 0, 1200, 0, 0];
    theta_min = [-160, -150, -200, -180, -120, -180];
    theta_max = [160, 15, 80, 180, 120, 180];
    P_target = [1500, 1200, 200]; % 目标位置
    lambda = 1; % 权重因子
    
    % 初始种群生成
    population_size = 100;
    num_generations = 100;
    crossover_rate = 0.8;
    mutation_rate = 0.1;
    
    % 随机生成初始种群
    population = zeros(population_size, 6);
    for i = 1:population_size
        for j = 1:6
            population(i, j) = theta_min(j) + (theta_max(j) - theta_min(j)) * rand;
        end
    end
    
    % 遗传算法主程序
    for generation = 1:num_generations
        % 适应度计算
        fitness_values = zeros(population_size, 1);
        for i = 1:population_size
            fitness_values(i) = fitness(population(i, :), P_target);
        end
        
        % 将适应度值转换为非负值
        min_fitness = min(fitness_values);
        fitness_values = fitness_values - min_fitness + 1; % 确保所有适应度值为正
        
        % 选择(轮盘赌算法)
        probabilities = fitness_values / sum(fitness_values);
        selected_indices = randsample(1:population_size, population_size, true, probabilities);
        selected_population = population(selected_indices, :);
        
        % 交叉
        new_population = zeros(population_size, 6);
        for i = 1:2:population_size
            if rand < crossover_rate
                crossover_point = randi([1, 5]);
                new_population(i, :) = [selected_population(i, 1:crossover_point), selected_population(i + 1, crossover_point + 1:end)];
                new_population(i + 1, :) = [selected_population(i + 1, 1:crossover_point), selected_population(i, crossover_point + 1:end)];
            else
                new_population(i, :) = selected_population(i, :);
                new_population(i + 1, :) = selected_population(i + 1, :);
            end
        end
        
        % 变异
        for i = 1:population_size
            if rand < mutation_rate
                mutation_point = randi([1, 6]);
                new_population(i, mutation_point) = theta_min(mutation_point) + (theta_max(mutation_point) - theta_min(mutation_point)) * rand;
            end
        end
        
        population = new_population;
    end
    
    % 输出最优解
    fitness_values = zeros(population_size, 1);
    for i = 1:population_size
        fitness_values(i) = fitness(population(i, :), P_target);
    end
    
    [~, best_index] = min(fitness_values);
    best_solution = population(best_index, :)
    best_fitness = fitness_values(best_index)
    % 正运动学计算函数
    function T = forward_kinematics(theta)
        a = [0, 300, 1200, 300, 0, 0];
        alpha = [0, -90, 0, -90, -90, -90];
        d = [600, 0, 0, 1200, 0, 0];
        T = eye(4);
        for i = 1:6
            A = [cosd(theta(i)), -sind(theta(i)) * cosd(alpha(i)), sind(theta(i)) * sind(alpha(i)), a(i) * cosd(theta(i));
                 sind(theta(i)), cosd(theta(i)) * cosd(alpha(i)), -cosd(theta(i)) * sind(alpha(i)), a(i) * sind(theta(i));
                 0, sind(alpha(i)), cosd(alpha(i)), d(i);
                 0, 0, 0, 1];
            T = T * A;
        end
    end
    
    % 适应度计算函数
    function E_error = fitness(theta, P_target)
        T = forward_kinematics(theta);
        P_actual = T(1:3, 4)';
        E_error = norm(P_target - P_actual);
    end
    
  • Python
  • import numpy as np
    from scipy.optimize import minimize
    
    # D-H参数
    a = [0, 300, 1200, 300, 0, 0]
    alpha = [0, -np.pi/2, 0, -np.pi/2, -np.pi/2, -np.pi/2]
    d = [600, 0, 0, 1200, 0, 0]
    theta_ranges = [(-160, 160), (-150, 15), (-200, 80), (-180, 180), (-120, 120), (-180, 180)]
    
    # 目标位置
    target = np.array([1500, 1200, 200])
    
    # 计算D-H矩阵
    def dh_matrix(a, alpha, d, theta):
        return np.array([
            [np.cos(theta), -np.sin(theta)*np.cos(alpha), np.sin(theta)*np.sin(alpha), a*np.cos(theta)],
            [np.sin(theta), np.cos(theta)*np.cos(alpha), -np.cos(theta)*np.sin(alpha), a*np.sin(theta)],
            [0, np.sin(alpha), np.cos(alpha), d],
            [0, 0, 0, 1]
        ])
    
    # 计算末端位姿
    def end_effector_position(thetas):
        T = np.eye(4)
        for i in range(6):
            T = T @ dh_matrix(a[i], alpha[i], d[i], np.radians(thetas[i]))
        return T[:3, 3]
    
    # 目标函数
    def objective(thetas):
        pos = end_effector_position(thetas)
        return np.linalg.norm(pos - target)
    
    # 初始猜测
    initial_guess = [0, -90, 0, 180, -90, 0]
    
    # 约束
    bounds = [(low, high) for low, high in theta_ranges]
    
    # 优化
    result = minimize(objective, initial_guess, bounds=bounds, method='SLSQP')
    optimal_thetas = result.x
    
    print("最优关节角度:", optimal_thetas)
    print("最小化误差:", result.fun)
    
    # 打印末端位置
    end_position = end_effector_position(optimal_thetas)
    print("末端位置:", end_position)
    

    技术文档

    完整内容请看下方~

    作者:Better Rose

    物联沃分享整理
    物联沃-IOTWORD物联网 » “华数杯”数学竞赛A题深度解析与代码分享:2024年赛题全攻略

    发表回复