Skip to content

Commit

Permalink
SPOT 4.0.0-RC.4
Browse files Browse the repository at this point in the history
- Fixed the ArmConfig.png image so that the body axis orientation is correct.
- Fixed a bug where if the user saves a GUI state with a diagram selected, when loading the GUI state it will load the diagram (this can lead to problems if you load the state and the diagram is missing or renamed). When loading states, the diagram dropdown should be set to default.
- Flip-flopped back to software PWM for the following reasons:
-- Hardware PWM is best for high frequency problems, where the the pulses are extremely fast. Because of the valve time on the thrusters, is does not make sense to have a high frequency PWM.
-- The minimum hardware PWM achievable on the PCA9685 is 24 Hz. This can work [see Yazan], without a great controller it wastes a lot of air.
-- This minimum PWM frequency also limits the minimum duty cycle that be commanded. At 24Hz, any duty cycle lower then 16.8% is not achievable (no air will come out). This results in a large dead zone where simple PD controllers struggle.
-  Because of the above, reverted the thruster check code and clean shutdown code to work with GPIO code and not the PCA9685.
- Created a software PWM Python script that is located on all platforms and in the Resources folder. This script runs as fast as possible when executed, and receives duty cycle commands via local UDP from an active diagram.
- Created a PWM management script that manages the remote starting and stopping of the PWM Python code.
- Fixed a bug where the acceleration in X was incorrect for all platforms in simulation (no derivative was being taken).
- Tweaked the gains and the starting conditions for the default experiment to have better results and smoother behavior.
- Reverted back to the data rate being 80% of the baseRate - while buffering still seems to be resolved, doing this seems to help when there are network latency problems in the lab.
  • Loading branch information
TheElectricDream committed Sep 8, 2023
1 parent b3a6353 commit e9b4b06
Show file tree
Hide file tree
Showing 14 changed files with 364 additions and 156 deletions.
131 changes: 131 additions & 0 deletions Custom_Library/NVIDIA_Jetson/PWM_Write.sx1509
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
classdef PWM_Write < matlab.System & coder.ExternalDependency
%
% System object template for a GPIO_Write block.
%
% This template includes most, but not all, possible properties,
% attributes, and methods that you can implement for a System object in
% Simulink.
%

% Copyright 2021 The MathWorks, Inc.
%#codegen
%#ok<*EMCA>

properties
% Specify custom variable names

end

properties (Nontunable)
% Public, non-tunable properties.
end

methods
% Constructor
function obj = PWM_Write(varargin)
% Support name-value pair arguments when constructing the object.
setProperties(obj,nargin,varargin{:});
end
end

methods (Access=protected)
function setupImpl(obj) %#ok<MANU>
if isempty(coder.target)
% Simulation setup code
else
coder.cinclude('sx1509_controller.h');
coder.ceval('initSX1509');
end
end

function stepImpl(obj, u1,u2,u3,u4,u5,u6,u7,u8)
if isempty(coder.target)
% Simulation output code
else
coder.cinclude('sx1509_controller.h');
coder.ceval('commandPWM', u1, u2, u3, u4, u5, u6, u7, u8);
end
end

function releaseImpl(obj) %#ok<MANU>
if isempty(coder.target)
% Simulation termination code
else
% Termination code for PCA9685
coder.cinclude('sx1509_controller.h');
coder.ceval('commandPWM', 0, 0, 0, 0, 0, 0, 0, 0);
coder.ceval('closeSX1509');
end
end
end

methods (Access=protected)
%% Define input properties
function num = getNumInputsImpl(~)
num = 8;
end

function num = getNumOutputsImpl(~)
num = 0;
end

function flag = isInputSizeMutableImpl(~,~)
flag = false;
end

function flag = isInputComplexityMutableImpl(~,~)
flag = false;
end

function validateInputsImpl(~, u)
if isempty(coder.target)
% Run input validation only in Simulation
validateattributes(u,{'double'},{'scalar'},'','u');
end
end

function icon = getIconImpl(~)
% Define a string as the icon for the System block in Simulink.
icon = 'PWM_Write';
end
end

methods (Static, Access=protected)
function simMode = getSimulateUsingImpl(~)
simMode = 'Interpreted execution';
end

function isVisible = showSimulateUsingImpl
isVisible = false;
end

function header = getHeaderImpl
header = matlab.system.display.Header('GPIO_Write','Title',...
'Debugging Block','Text',...
['This block allows you to control the PWM pins on the SX1509 board via I2C.' ...
' The inputs are the duty cycle commands for thrusters 1-8 in order (input #1 is thruster #1).']);
end

end

methods (Static)
function name = getDescriptiveName()
name = 'PWM_Write';
end

function b = isSupportedContext(context)
b = context.isCodeGenTarget('rtw');
end

function updateBuildInfo(buildInfo, context)
if context.isCodeGenTarget('rtw')
srcDir = fullfile(fileparts(mfilename('fullpath')),'src');
includeDir = fullfile(fileparts(mfilename('fullpath')),'include');
addIncludePaths(buildInfo,includeDir);
% Add the source and header files to the build
addIncludeFiles(buildInfo,'sx1509_controller.h',includeDir);
addSourceFiles(buildInfo,'sx1509_controller.cpp',srcDir); % Assuming .cpp extension
end
end
end
end
Binary file modified Custom_Library/NVIDIA_Jetson/Validate_PWM_Write.slx
Binary file not shown.
Binary file not shown.
24 changes: 24 additions & 0 deletions Custom_Library/NVIDIA_Jetson/include/sx1509_controller.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef GPIO_CONTROL_H
#define GPIO_CONTROL_H

#include <cstdint>

// SX1509 registers and constants
#define SX1509_REG_I2C_DEVICE_ADDR 0x3E
#define SX1509_REG_CLOCK 0x1E
#define SX1509_REG_MISC 0x1F
#define SX1509_REG_LED_DRIVER_ENABLE 0x20
#define SX1509_REG_I_ON_0 0x10 // Base register for bank A LED drivers

// Functions declarations for SX1509

// Initialization and configuration of SX1509
void writeRegister(uint8_t reg, uint8_t value);
int initSX1509();
void closeSX1509();
void setPWM(uint8_t channel, uint8_t value);
void commandPWM(float PWM1, float PWM2, float PWM3, float PWM4,
float PWM5, float PWM6, float PWM7, float PWM8);


#endif // GPIO_CONTROL_H
155 changes: 0 additions & 155 deletions Custom_Library/NVIDIA_Jetson/src/pca9685_controller.bak

This file was deleted.

75 changes: 75 additions & 0 deletions Custom_Library/NVIDIA_Jetson/src/sx1509_controller.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#include <cmath>

// SX1509 registers and constants
#define SX1509_REG_I2C_DEVICE_ADDR 0x3E // You may need to adjust this based on your setup.
#define SX1509_REG_CLOCK 0x1E
#define SX1509_REG_MISC 0x1F
#define SX1509_REG_LED_DRIVER_ENABLE 0x20
#define SX1509_REG_I_ON_0 0x10 // Base register for bank A LED drivers

int FD_SX;

void writeRegister(uint8_t reg, uint8_t value) {
uint8_t data[2] = {reg, value};
if (write(FD_SX, data, 2) != 2) {
std::cout << "Failed to write to I2C device" << std::endl;
}
}

int initSX1509() {
const char* device = "/dev/i2c-8";
int address = SX1509_REG_I2C_DEVICE_ADDR;

FD_SX = open(device, O_RDWR);
if (FD_SX < 0) {
std::cout << "Failed to open I2C device" << std::endl;
return FD_SX;
}

if (ioctl(FD_SX, I2C_SLAVE, address) < 0) {
std::cout << "Failed to select I2C device" << std::endl;
close(FD_SX);
return -1;
}

// Configure oscillator and divider
writeRegister(SX1509_REG_CLOCK, 0x0F); // Use 500Hz
writeRegister(SX1509_REG_MISC, 0x07); // Use f/128 divider

// Enable LED driver on bank A (pins 0-7)
writeRegister(SX1509_REG_LED_DRIVER_ENABLE, 0xFF);

std::cout << "I2C Opened Successfully for SX1509:" << FD_SX << std::endl;

return FD_SX;
}

void closeSX1509() {
close(FD_SX);
}

void setPWM(uint8_t channel, uint8_t value) {
if (channel >= 0 && channel < 8) {
writeRegister(SX1509_REG_I_ON_0 + channel, value);
} else {
std::cout << "Invalid channel number for SX1509" << std::endl;
}
}

void commandPWM(float PWM1, float PWM2, float PWM3, float PWM4,
float PWM5, float PWM6, float PWM7, float PWM8) {

float duties[8] = {PWM1, PWM2, PWM3, PWM4, PWM5, PWM6, PWM7, PWM8};

// Convert percentages to SX1509's 0-255 range
for (int channel = 0; channel <= 7; channel++) {
uint8_t pwmValue = static_cast<uint8_t>((duties[channel] / 100.0) * 255.0);
printf("The value is: %f\n", pwmValue);
setPWM(channel, pwmValue);
}
}
Binary file modified Template_Files/GUI_v4_0_Main.mlapp
Binary file not shown.
Binary file modified Template_Files/Resources/ArmConfig.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Template_Files/Resources/SPOTGUI_DEFAULT.mat
Binary file not shown.

0 comments on commit e9b4b06

Please sign in to comment.