Matlab快速入门 基础语法教学

1. 基础语法:抛弃循环,拥抱矩阵

在其他语言里处理一堆连续数据通常需要 for 循环,但在 MATLAB 里,矩阵运算会自动向量化,一行代码就能解决。

复制代码
% 这是一个注释。MATLAB 的脚本通常以 .m 结尾

% 1. 定义一个状态向量,比如 [x, y, yaw, v]
state = [10.5, 20.1, 0.5, 5.0];

% 2. 定义一段参考轨迹的 x 和 y 坐标 (从 0 到 100,步长为 1)
ref_x = 0:1:100;

% 假设这条路径是一个简单的正弦曲线,直接对整个矩阵操作
ref_y = 5 * sin(ref_x / 10);

% 3. 矩阵乘法与点乘(极其重要!)
% 如果你想对所有 ref_y 的值进行平方,不能直接用 ^2。
% 必须用点乘 .^2(表示对矩阵里的每一个元素独立进行平方操作)
ref_y_squared = ref_y .^ 2;

2. 强大的可视化:让数据说话

算法调试最重要的一环就是看图,验证逻辑是否符合预期。MATLAB 的 plot 绘图功能极其强大且直观。

复制代码
% 创建一个新画布
figure;

% 绘制规划好的参考轨迹,用黑色(k)虚线(--)表示
plot(ref_x, ref_y, 'k--', 'LineWidth', 2);
hold on; % 关键命令:保持当前图像,允许在上面继续叠加画图,否则新图会覆盖旧图

% 模拟控制算法跑出来的实际轨迹 (给原本的路径加上一点随机误差)
% randn 生成正态分布的随机数矩阵
%randn:生成均值 = 0,标准差 = 1的高斯随机噪声
%randn(x,y):生成x行y列的的高斯随机噪声
actual_y = ref_y + 0.5 * randn(1, length(ref_x));   


% 绘制实际轨迹,用红色(r)实线(-)表示
%'LineWidth', 1.5:线条宽度为1.5
plot(ref_x, actual_y, 'r-', 'LineWidth', 1.5);

% 添加图例、坐标轴标签和标题
legend('参考轨迹', '实际跟踪轨迹');
xlabel('全局 X 坐标 (m)');
ylabel('全局 Y 坐标 (m)');
title('路径跟踪逻辑验证');
grid on; % 打开背景网格

3. 函数与控制流

MATLAB 的控制流(if, for, while)逻辑很清晰,最大的区别是不需要大括号 {},所有代码块都用 end 来结尾。

复制代码
% 定义一个计算横向误差的简易函数(必须写在脚本最下面,或者单独存为一个 .m 文件)
function max_error = calculate_cte(ref_y, actual_y)
    % 矩阵直接相减,并求绝对值
    diff = abs(ref_y - actual_y);
    
    % 寻找整个数组里的最大误差
    max_error = max(diff);
    
    % 条件判断
    if max_error > 1.0
        disp('警告:横向控制误差过大!');        % disp 用于在终端打印输出信息
    else
        disp('控制精度良好。');
    end
end

4. 高阶武库:Toolbox (工具箱)

MATLAB 最值钱的其实不是它的基础语法,而是集成了极其专业的工具箱。当你熟悉了上面的基础操作后,可以直接去官方文档(在软件里按 F1)搜索并调用现成的接口,避免重复造轮子:

  • Control System Toolbox:用于传递函数建模、状态空间方程定义、PID 自动调参、LQR 求解等。

  • Automated Driving Toolbox:直接提供了现成的车辆动力学/运动学模型、坐标系转换函数以及各种路径规划算法的底层接口。

  • Optimization Toolbox :当面临复杂的二次规划(QP)或非线性优化问题时,调用里面的 quadprog 等函数可以迅速验证求解逻辑。

5. 逻辑索引 (Logical Indexing):过滤数据的神兵利器

在 C++ 里,如果你想找出数组里所有"大于 90 的 CPU 占用率"并把它们清零,你需要写一个 for 循环加上 if 判断。在 MATLAB 里,这叫逻辑索引,一行代码秒杀:

复制代码
% 假设这是你从实车日志里读取的 10 个周期的 CPU 总占用率
cpu_usage = [21.5, 30.2, 95.1, 98.0, 45.0, 88.5, 92.3, 15.0, 10.5, 99.9];

% 1. 找出所有大于 90 的报警数据(返回一个只包含 0 和 1 的逻辑矩阵)
is_danger = cpu_usage > 90; 
% 此时 is_danger = [0, 0, 1, 1, 0, 0, 1, 0, 0, 1]

% 2. 提取出所有危险值(直接把逻辑矩阵当做下标塞进去!)
danger_values = cpu_usage(is_danger);
% danger_values = [95.1, 98.0,92.3,99.9]


% 3. 把所有大于 90 的异常值强行"削平"到 90(一键赋值)
cpu_usage(cpu_usage > 90) = 90;
% cpu_usage = [21.5, 30.2, 90, 90, 45.0, 88.5, 90, 15.0, 10.5, 90]

6. matlab跨文件调用函数

规则一:文件名必须等于函数名(铁律)

这是 MATLAB 最独特的规定。如果你想写一个能在其他文件里被调用的函数,你必须:

  1. 新建一个 .m 文件。

  2. 里面定义的主函数名称 ,必须和文件的命名一模一样。

例如:写一个计算横向误差的函数 新建一个文件,命名为 calculate_cte.m,里面的代码这样写:

复制代码
% 文件名:calculate_cte.m
function max_error = calculate_cte(ref_y, actual_y)
    diff = abs(ref_y - actual_y);
    max_error = max(diff);
end
规则二:同文件夹下,直接"裸调"

如果你的主运行脚本(比如 main.m)和刚才写的函数文件(calculate_cte.m)保存在同一个文件夹里。 你不需要做任何引入操作,直接写函数名就可以调用!

复制代码
% 文件名:main.m (和 calculate_cte.m 在同一个目录下)

ref = [0, 0, 0];
act = [0.1, -0.2, 0.05];

% 直接裸调,MATLAB 会自动在当前文件夹里寻找同名的 .m 文件
error = calculate_cte(ref, act); 

disp(['最大横向误差是: ', num2str(error)]);

1.向量

1.1 创建方式

1.1.1 直接输入各个元素

[]包裹整个数组,元素之间用空格或者逗号隔开(行向量 ),元素之间用分号隔开(列向量),也可以混合使用用来生成矩阵

1.1.2 冒号创建
复制代码
格式:x=开始:间隔:结尾
间隔可以省略,默认是1

1.2 向量的运算

1.2.1 加法

直接对应元素相加即可

1.2.2 相乘

向量乘法,即向量内积

a·b=a1b1+a2b2+......+anbn

将该运算定义为.*(点乘)

matlab中还定义了dot()函数,将点乘结果进行相加,相当于sum(ans)

1.2.3矩阵索引

  • 索引:取矩阵里的元素,用(行,列)
    • A(2,3) → 第二行第三列(值是6)
    • A(:,1) → 第一列所有元素([1;4;7])
    • A(1,:) → 第一行所有元素([1,2,3])

2.输入与输出

2.1 输入函数--input()

input函数:用于在命令行获取用户输入的数值、字符串或表达式等,并将其作为变量的值。

格式:value = input('提示信息');这里的提示信息是显示给用户的文本,提示用户输入内容。用户输入完成后,按下回车键,输入的内容将被赋给value变量。

2.2 输出函数

disp函数:用于在命令行显示变量的值、文本信息等。它会自动换行显示内容,并且不会显示变量名,只显示其值。
fprintf函数:按照指定的格式将数据输出到命令行或文件中。它可以对输出内容进行格式化,使其更加规范和美观。

4.循环结构

4.1 for循环

语法格式:

复制代码
for 循环变量 = 起始值:步长:终止值		% 步长默认是1
    % 循环体,这里是要重复执行的代码块
end

所有函数跟循环都是以end作为结尾的

5.函数体

函数一般在.m文件中编写,由function语句引导,基本结构为:

复制代码
function [输出参数1, 输出参数2,...] = 函数名(输入参数1, 输入参数2,...)
    % 函数体:在这里进行各种计算、操作等,以实现函数的功能
    % 根据输入参数计算得到输出参数的值
end

function z = f(x,y)
%   该函数计算|x|+|y|,并将结果返回给z
if x>=0&&y>=0
    z=x+y;
elseif x<=0&&y>=0
    z=y-x;
elseif x>=0&&y<=0
    z=x-y;
else
    z=-(x+y);
end

6.绘图函数

6.1 plot()函数

plot(X,Y) 创建 Y 中数据对 X 中对应值的二维线图。

要绘制由线段连接的一组坐标,请将 X 和 Y 指定为相同长度的向量。

xlabel:设置X轴标签

ylabel:设置Y轴标签

title:设置图像标题

grid on:显示网格信息

axis设置坐标轴范围

复制代码
x=0:0.01:2*pi;
y=sin(x);

plot(x,y)
grid on;% 显示网格
xlabel("x");% 设置x轴标签
ylabel("sin(x)")% 设置y轴标签
title("函数y=sin(x)")% 设置标题
axis([0 2*pi -1.5 1.5]) %设置横纵坐标显示范围
axis square %生成正方形图

7.特殊的矩阵函数

7.1 全零矩阵

zeros(M)函数:生成M x M大小的全零矩阵
zeros(M,N)函数:生成M x N大小的全零矩阵

7.2 全1矩阵

ones(M)函数:生成M x M大小的全1矩阵
ones(M,N)函数:生成M x N大小的全1矩阵

也可以使用矩阵和一个标量相加减,来构造任何元素的矩阵

7.3 随机矩阵

7.3.1 rand()函数

rand(M)函数:生成M x M大小的随机矩阵,元素在(0,1)之间服从均匀分布
rand(M,N)函数:生成M x N大小的随机矩阵,元素在(0,1)之间服从均匀分布

7.3.2 randn()函数

randn(M)函数:生成M x M大小的随机矩阵,元素服从均值为0,方差为1的正态分布
randn(M,N)函数:生成M x N大小的随机矩阵,元素服从均值为0,方差为1的正态分布


"MATLAB 起手式"

1. clc; (Clear Command Window)

  • 作用清空命令行窗口

  • 大白话 :相当于"擦黑板"。把你之前在控制台里打印的一大堆杂乱的数字、报错信息、调试日志全部清空,让屏幕变得干干净净。它不会删除你计算好的数据,只是让视觉上清爽。

2. clear all; (Clear Workspace)

  • 作用清空工作区中的所有变量

  • 大白话 :这是最关键的"排雷"命令。如果你不加这句,你上一次运行代码时残留在内存里的变量(比如上次算出来的轨迹矩阵 x),会直接带入到这一次的运行中。这极其容易导致隐蔽的 Bug(比如你以为你在算新的逻辑,其实在用旧的数据)。

  • 💡 进阶小贴士 :在新版 MATLAB 中,其实推荐只写 clear;。因为 clear all; 不仅会清空变量,还会把你电脑缓存的底层函数也清空,导致代码运行速度变慢。不过在工程界,大家早就写顺手了,看到 clear all; 也很正常。

3. close all; (Close All Figures)

  • 作用关闭所有的绘图窗口

4. format long; (Format Long)

  • 作用设置控制台的数字显示格式为"长格式"

  • 大白话 :MATLAB 默认在控制台打印小数时,只显示 4 位小数(叫 format short,比如显示 3.1416)。但你们在做规控算法时,底层都是 double(双精度浮点数)。加上这句后,控制台打印的数字会直接显示 15 位小数 (比如 3.141592653589793)。这对于排查精度丢失或微小的计算误差非常有用。


global 关键字

在 MATLAB(以及 Python、C++ 等大多数编程语言)中,global 关键字的核心作用是**"打破作用域(Scope)的隔离墙",让一个变量可以在不同的函数、脚本甚至整个工作区之间共享读写**,而不需要通过函数的参数传来传去。

1. 基本语法与使用规范

在 MATLAB 中使用全局变量,有一个必须遵守的铁律:使用该变量的所有地方(无论是主脚本还是子函数),都必须提前用 global 声明一次。

示例:主脚本与子函数共享数据

假设你有一个主脚本 main.m 和一个函数 add_speed.m

第一步:在主脚本中声明并赋值

复制代码
% 文件名:main.m
clc; clear all; close all;

% 1. 声明一个全局变量(行业惯例:全局变量通常全大写,以防和普通变量混淆)
global CAR_SPEED; 

% 2. 给它赋值
CAR_SPEED = 60; 

disp(['加速前,车速为: ', num2str(CAR_SPEED)]);

% 3. 调用外部函数(注意:不需要把 CAR_SPEED 作为参数传进去)
add_speed();

disp(['加速后,车速变为: ', num2str(CAR_SPEED)]);

第二步:在函数中再次声明并使用

复制代码
% 文件名:add_speed.m
function add_speed()
    % 1. 必须再次声明!告诉 MATLAB:"我要去大厅拿那个叫 CAR_SPEED 的公共变量"
    global CAR_SPEED; 
    
    % 2. 直接读取并修改它
    CAR_SPEED = CAR_SPEED + 10; 
end

运行 main.m 后,你会发现函数内部成功修改了外部的变量,最终输出的车速变成了 70。


2. 使用 global 的三大核心规则

  1. 先声明,后赋值 :永远要把 global VAR_NAME 写在给它赋值的前面。如果你先写 VAR_NAME = 10; 然后再写 global VAR_NAME;,MATLAB 会直接报错或者把你的值清空。

  2. 两头都要写 :主工作区要写 global,函数里面也要写 global。如果函数里忘了写,MATLAB 会把它当成函数内部的一个全新局部变量,根本不会去碰那个全局变量。

  3. 清除全局变量的特殊命令 :普通的 clear 或者 clear all 是可以清除它的。但如果你只想单独清除某个全局变量,需要用 clear global CAR_SPEED

相关推荐
笨笨马甲2 小时前
Qt 嵌入式开发快速搭建交叉编译环境
开发语言·qt
张人玉2 小时前
C# 中的 MVC、MVP、MVVM 模式详解
开发语言·c#·mvc·mvvm·mvp
dgfhf2 小时前
高性能计算资源调度
开发语言·c++·算法
Lhan.zzZ2 小时前
Qt绘图探秘:如何避免多QPainter冲突引发的程序崩溃
开发语言·c++·qt
Ralph_Y2 小时前
C++:迭代器失效
开发语言·c++
smart margin2 小时前
Python安装教程
开发语言·python
浩瀚之水_csdn2 小时前
++ Lambda 表达式详解
java·jvm·windows
janthinasnail2 小时前
升级docker-buildx
docker·容器
weixin_307779132 小时前
OpenClaw-CN 安全增强方案:从理念到落地的全面剖析
开发语言·人工智能·算法·安全·语言模型