I'm trying to create a figure where the user can select cells to turn on or off. Then, the user can click a button 'Enter' to save the board as an array. I successfully found a way to create interactivity in my plot thanks to a very useful explanation I found here. I just made some changes to suit my needs.
However, I can't find a way to save the board. The button is working (or at least isn't not working), but the data isn't saved. And I don't know how to fix that. Any help would be appreciated.
Here is my code:
function CreatePattern
hFigure = figure;
hAxes = axes;
axis equal;
axis off;
hold on;
% create a button to calculate the difference between 2 points
h = uicontrol('Position',[215 5 150 30],'String','Enter','Callback', #SaveArray);
function SaveArray(ButtonH, eventdata)
global initial
initial = Board;
close(hFigure)
end
N = 1; % for line width
M = 20; % board size
squareEdgeSize = 1;
% create the board of patch objects
hPatchObjects = zeros(M,M);
for j = M:-1:1
for k = 1:M
hPatchObjects(M - j+ 1, k) = rectangle('Position', [k*squareEdgeSize,j*squareEdgeSize,squareEdgeSize,squareEdgeSize], 'FaceColor', [0 0 0],...
'EdgeColor', 'w', 'LineWidth', N, 'HitTest', 'on', 'ButtonDownFcn', {#OnPatchPressedCallback, M - j+ 1, k});
end
end
%global Board
Board = zeros(M,M);
playerColours = [1 1 1; 0 0 0];
xlim([squareEdgeSize M*squareEdgeSize]);
ylim([squareEdgeSize M*squareEdgeSize]);
function OnPatchPressedCallback(hObject, eventdata, rowIndex, colIndex)
% change FaceColor to player colour
value = Board(rowIndex,colIndex);
if value == 1
set(hObject, 'FaceColor', playerColours(2, :));
Board(rowIndex,colIndex) = 0; % update board
else
set(hObject, 'FaceColor', playerColours(1, :));
Board(rowIndex,colIndex) = 1; % update board
end
end
end
%imwrite(~pattern,'custom_pattern.jpeg')
Related
I'm making an action RPG in Love2d, and I moved all of my player code into a separate Lua script for the sake of organization - but now upon attempting to use player.load, I get this error:
Error
main.lua:22: attempt to index global 'player' (a boolean value)
Traceback
main.lua:22: in function 'load'
[C]: in function 'xpcall'
[C]: in function 'xpcall'
this is my main.lua script:
-- RPG PROJECT IN LOVE2D
-- debug mode
debug = true -- SET FALSE BEFORE SHIPPING
-- ROOM CHART:
-- 0 - Title
-- 1 - Overworld
-- 2 - Shop
-- 3 - Boss Room
Room = 0
-- PLAYER STATE CHART:
-- 0 - free
-- 1 - attacking
-- 3 - can't move
function love.load(dt)
player = require 'Scripts/player'
player.load()
sti = require 'Libraries/sti'
gameMap = sti('Maps/overworld.lua')
menuImg = love.graphics.newImage('Assets/Menu.png')
love.window.setMode(800, 600)
end
function love.draw(dt)
if Room == 0 then
love.graphics.draw(menuImg, 0, 0)
end
if Room == 1 then
gameMap:draw()
player.draw()
end
if debug == true then
love.graphics.print("Current FPS: "..tostring(love.timer.getFPS( )), 10, 10)
end
end
function love.update(dt)
if Room == 0 then
if love.keyboard.isDown('space') then
Room = 1
end
end
if Room == 1 then
player.Update(dt)
if love.keyboard.isDown('escape') then
Room = 0
end
end
if love.keyboard.isDown('t') then
debug = not debug
end
end
and this is my player.lua script:
-- PLAYER SCRIPT
player = {x = 50, y = 50, speed = 3, state = 0, img = nil}
function player.load()
playerRight = love.graphics.newImage('Assets/playerRight.png')
playerLeft = love.graphics.newImage('Assets/playerLeft.png')
playerUp = love.graphics.newImage('Assets/playerUp.png')
playerDown = love.graphics.newImage('Assets/playerDown.png')
player.img = playerDown
end
function GetInput()
if player.state == 0 or player.state == 1 then
if love.keyboard.isDown('w') then
player.y = player.y - player.speed
player.img = playerUp
elseif love.keyboard.isDown('s') then
player.y = player.y + player.speed
player.img = playerDown
end
if love.keyboard.isDown('a') then
player.x = player.x - player.speed
player.img = playerLeft
elseif love.keyboard.isDown('d') then
player.x = player.x + player.speed
player.img = playerRight
end
end
end
function player.update(dt)
GetInput()
end
function player.draw()
love.graphics.draw(player.img, player.x, player.y)
end
Any help would be much appreciated!
Here's my folders as well, just in case it's a path issue:
UPDATE:
I solved it by renaming the player object to oPlayer, that was what was giving me an error.
I have severall Hints for you
Unclear
It looks you write it under Linux but should it also run under Windows?
If so, use OS independent folder delimiter ( the dot ) in require().
Example
player = require 'Scripts.player'
In General: Dont use Slash / Backslash \ in require()
Tip: LÖVE uses LuaJIT with modified Lua 5.1 check the Windows OS is easy
(For deciding to use Slash or Backslash (not in/for require()))
Clear
As #Luke100000 mentioned...
A Script for require has to return something.
If not than only a true wil be cached and a next require returns only true.
Therefore your player.lua content should be...
-- player.lua
local player = {x = 50, y = 50, speed = 3, state = 0, img = nil}
-- player.load() will be local
-- GetInput() wil be global
-- And the last line...
return(player)
I am trying to solve a 3 Degree Of Freedom vessel-crane system in MATLAB using ode45. In my ode function, the vessel motion is determined by simple spring and damper constants, but the device below the main hoist system, a cranemaster, has a displacement-dependent stiffness and thus depends on one of the Degrees Of Freedom. To determine this value, I use the interp1 function to determine the stiffness from a dataset:
vq = interp1(x,v,xq,method,extrapolation)
This all works fine, but only when I add the extrapolation option in the interp1 function, even though the xq values all fall inside the dataset x-values. If I do not specify extrapolation, the function returns NAN.
I have checked if the stiffness values in the dataset make sense by taking the median value as a constant value and then the ode45 solver works just fine and the displacement never falls outside of the dataset. I have also noticed that if I switch to ode23 as a solver, it also works. This all makes me believe it has something to do with the solving method and the stepsize the ode solver takes as its initial value.
I have provided (a simplified version of) my code and a picture of the system to get a feel for the problem. I know that switching to ode23 solves the problem but I would like to understand why and, if possible, stay with ode45 as it is a more general solver.
Any help would be appreciated!
Regards,
Diederik
Overview of the system I am solving
close all
tspan = [0 100];
x0 = [0.0; 0; 0.0; 0; 0.0; 0]; % initial disp. and vel. is 0. for all 3 DOF.
% x = [z; zdot; theta; thetadot; u; udot]
[t,x] = ode45(#Three_DOF,tspan,x0);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Plots
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
figure()
subplot(2,1,1)
plot(t,x(:,5),'color','b','LineWidth',1)
grid on
xlabel('Time (s)')
ylabel('Displacement (m)')
title('Displacement Vs Time')
subplot(2,1,2)
plot(t,x(:,6),'color','#D95319','LineWidth',1)
grid on
xlabel('Time (s)')
ylabel('Velocity (m/s)')
title('Velocity Vs Time')
function [dxdt] = Three_DOF(t,x)
% vessel parameters
m = 570.5e6;
m55 = 4.591e12;
mh = 200e3;
c33 = 3.83952e8;
c55 = 3.66116e12;
wnh = 0.360;
wnp = 0.596;
a33 = (c33-wnh^2*m)/wnh^2;
a55 = (c55-wnp^2*m55)/wnp^2;
zeta33 = 0.386;
zeta55 = 0.121;
b33 = zeta33*2*sqrt(c33*(m+a33));
b55 = zeta55*2*sqrt(c55*(m55+a55));
Fa = 153e6;
Ma = 3.013e9;
w1 = 0.21/0.36;
w2 = 0.18/0.28;
%%%% Cable parameters
k_c = 496e6;
b_c = 5.01e6;
%%% CRANEMASTER parameters
x_data = [-2.0; -1.87; -1.73; -1.60; -1.47; -1.33; -1.20; -1.07; -0.93; -0.8; -0.67; -0.53; -0.4; -0.27; -0.13; 0.0; 0.13; 0.27; 0.40; 0.53; 0.67; 0.80; 0.93; 1.07; 1.20; 1.33; 1.47; 1.60; 1.73; 1.87; 2.0];
k_data = [760; 792.1; 784.8; 813.9; 828.4; 850.2; 879.3; 901.1; 922.9; 959.2; 981.0; 1010.1; 1039.1; 1068.2; 1104.5; 1133.6; 1177.2; 1206.3; 1242.6; 1286.2; 1329.8; 1373.4; 1409.7; 1460.6; 1511.5; 1562.3; 1620.5; 1671.3; 1729.5; 1794.9; 1853];
k_cm = 30000*interp1(x_data,k_data,x(5));%,'linear','extrap');
%k_cm = 30000*1133.61; % middle value of dataset k_data
b_cm = 6e4;
l = 217.5;
% Matrices & solve
Mass = [m+a33 0 0; 0 m55+a55 0; 0 0 mh];
k = [c33+k_c -k_c*l -k_c; -k_c*l c55+k_c*l^2 k_c*l; -k_c k_c*l k_c+k_cm];
b = [b33+b_c -b_c*l -b_c; -b_c*l b55+b_c*l^2 b_c*l; -b_c b_c*l b_c+b_cm];
F = [Fa*sin(w1*t); Ma*sin(w2*t); 0];
EOM = Mass\(F-b*([x(2); x(4); x(6)])-k*([x(1); x(3); x(5)]));
dxdt = [x(2); EOM(1); x(4); EOM(2); x(6); EOM(3)];
% x = [z; zdot; theta; thetadot; u; udot]
end
I have the following 2n*π-periodic function F(x) = sin(x/n) and I need to graph the dx/dt = γ - F(x) on the segment from 0 to 2pi. So it should look like this. I tried to do it matlab this way:
gamma = 1.01;
n=3;
[t,phi] = ode45(#(t,x)gamma-sin(x/n), [0,400], pi);
[t1,phi1] = ode45(#(t,x)gamma-sin(x/n), [112,400], 0);
[t2,phi2] = ode45(#(t,x)gamma-sin(x/n), [231,250], 0);
figure();
plot(t, phi, 'k', t1, phi1, 'k', t2, phi2, 'k');
ylim([0 2*pi]);
yticks([0 pi 2*pi]);
yticklabels(["0" "\pi" "2\pi"]);
grid on; grid minor;
title('\itsin(x/n)')
but I only got something like this. So there the lines are not transferred, but "begin anew". does anyone here know how to do that?
I get a plot similar to your first sketch, and based on your code in the comments (in future, put such additions into the question itself, use formatting to mark it as addition, and cite it then in the comment) with the changes
use pi as initial point as seen in the drawing,
use the options of the ODE solver to restrict the step size, directly and by imposing error tolerances
your original time span covers about 3 periods, reduce this to [0, 200] to get the same features as the drawing.
gamma = 1.01; n=3;
opts = odeset('AbsTol',1e-6,'RelTol',1e-9,'MaxStep',0.1);
[t, phi] = ode45(#(t,x)gamma-sin(x/n), [0,200], pi, opts);
phi = mod(phi, 2*pi);
plot(t, phi, 'k');
ylim([0 2*pi]); yticks([0 pi 2*pi]); yticklabels(["0" "\pi" "2\pi"]);
grid on; grid minor;
title('\itsin(x/n)')
To get more elaborate, use events to get points on the numerical solution where it exactly crosses the 2*pi periods, then use that to segment the solution plot (styling left out)
function [ res, term, dir ] = event(t,y)
y = mod(y+pi,2*pi)-pi;
res = [ y ];
dir = [1]; % only crossing upwards
term = [0]; % do not terminate
end%function
opts = odeset(opts,'Events',#(t,y)event(t,y));
sol = ode45(#(t,x)gamma-sin(x/n), [0,200], pi, opts);
tfs = [ sol.xe; sol.x(end) ]
N = length(tfs)
clf;
t0 = 0;
for i=1:N
tf = tfs(i);
t = linspace(t0+1e-2,tf-1e-2,150);
y = deval(sol,t); % octave: deval=#(res,t) interp1(res.x, res.y,t)
y = mod(y,2*pi);
plot(t, y);
hold on;
t0=tf;
end;
hold off;
I am facing a issue, here is my script. some end or bracket issue but I have checked noting is missing.
function [h, display_array] = displayData(X, example_width)
%DISPLAYDATA Display 2D data in a nice grid
% [h, display_array] = DISPLAYDATA(X, example_width) displays 2D data
% stored in X in a nice grid. It returns the figure handle h and the
% displayed array if requested.
% Set example_width automatically if not passed in
if ~exist('example_width', 'var') || isempty(example_width)
example_width = round(sqrt(size(X, 2)));
end
% Gray Image
colormap(gray);
% Compute rows, cols
[m n] = size(X);
example_height = (n / example_width);
% Compute number of items to display
display_rows = floor(sqrt(m));
display_cols = ceil(m / display_rows);
% Between images padding
pad = 1;
% Setup blank display
display_array = - ones(pad + display_rows * (example_height + pad), ...
pad + display_cols * (example_width + pad));
% Copy each example into a patch on the display array
curr_ex = 1;
for j = 1:display_rows
for i = 1:display_cols
if curr_ex > m,
break;
end
% Copy the patch
% Get the max value of the patch
max_val = max(abs(X(curr_ex, :)));
display_array(pad + (j - 1) * (example_height + pad) +
(1:example_height), ...
pad + (i - 1) * (example_width + pad) +
(1:example_width)) = ...
reshape(X(curr_ex, :),
example_height, example_width) / max_val;
curr_ex = curr_ex + 1;
end
if curr_ex > m,
break;
end
end
% Display Image
h = imagesc(display_array, [-1 1]);
% Do not show axis
axis image off
drawnow;
end
ERROR:
displayData
parse error near line 86 of file C:\Users\ALI\displayData.m
syntax error
Pls guide which is the error in the script, this script is already written in
the coursera so its must be error free.
You seem to have modified the code, and moved the "ellipsis" operator (i.e. ...) or the line that is supposed to follow it, in several places compared to the original code in coursera.
Since the point of the ellipsis operator is to appear at the end of a line, denoting that the line that follows is meant to be a continuation of the line before, then moving either the ellipsis or the line below it will break the code.
E.g.
a = 1 + ... % correct use of ellipsis, code continues below
2 % treated as one line, i.e. a = 1 + 2
vs
a = 1 + % without ellipsis, the line is complete, and has an error
... 2 % bad use of ellipsis; also anything to the right of '...' is ignored
vs
a = 1 + ... % ellipsis used properly so far
% but the empty line here makes the whole 'line' `a = 1 +` which is wrong
2 % This is a new instruction
I have yet to find a complete example for using the mkfifo() function online. I am able to make the fifo like this:
mkfifo("file",777)
But when I fopen() this file, Octave just hangs. What is the proper way to create, queue, and dequeue bytes from a mkfifo object?
I would like to create an in-memory fifo in Octave (on-disk is fine too) and read and write it from the same Octave script. My project is running in real time, and so I need a buffer so that I can fill and drain from the same Octave script. I've searched for a fifo library with zero results. Even just creating a vector and pushing and popping will suit my needs. I tried this myself, but I'm running into object oriented programming design problems because Octave does not allow pass by reference or pointers.
There are two issues. First: mkfifo expects mode as integer with base 10, if you write "777" you think in octal, base 8. Second: mkfifo uses umask to modify the permissions to (mode & ~umask) (See man 3)
As example:
fn=tempname
[ERR, MSG] = mkfifo (fn, base2dec("744", 8))
stat(fn)
fn = /tmp/oct-83UCBR
ERR = 0
MSG =
ans =
scalar structure containing the fields:
dev = 2053
ino = 3408172
mode = 4580
modestr = prwxr--r--
nlink = 1
uid = 1000
gid = 1000
rdev = 0
size = 0
atime = 1.4311e+09
mtime = 1.4311e+09
ctime = 1.4311e+09
blksize = 4096
blocks = 0
As you can see the modestr is now prwxr--r-- as you would expect from octal 744
Now you can open one end of the FIFO:
fid = fopen (fn, "r")
Of course this blocks until the other end of the fifo gets connected.
The fifo class works, but only up to a certain size. The max size in bytes of a fifo can be found by running:
cat /proc/sys/fs/pipe-max-size
1048576
Below is the code that I wrote for an in-memory fifo. It's fairly crude but it works well:
1; % Prevent Octave from thinking that this is a function file
global fifoCount fifoSamples fifoFiles fifoFids fifoDataType
fifoSamples = zeros(0);
fifoCount = 0;
fifoFiles = cell(1);
fifoFids = zeros(0);
fifoDataType = 'single';
fifoDataTypeSize = 4;
fifoMaxBytes = 1048576; % this is operating system enforced, changing here will not help
function [] = o_fifo_write(index, data)
global fifoCount fifoSamples fifoFiles fifoFids fifoDataType
wrcount = fwrite(fifoFids(index), data, fifoDataType);
[sz,~] = size(data);
fifoSamples(index) = fifoSamples(index) + sz;
if( sz ~= wrcount )
disp(sprintf('o_fifo_write was given %d samples but wrote %d', sz, wrcount));
end
if( ~iscolumn(data) )
disp('data must be columnar in o_fifo_write');
end
end
function [data] = o_fifo_read(index, count)
global fifoCount fifoSamples fifoFiles fifoFids fifoDataType
[data, rdcount] = fread(fifoFids(index), count, fifoDataType);
[sz,~] = size(data);
fifoSamples(index) = fifoSamples(index) - sz;
if( sz ~= rdcount || sz ~= count )
disp(sprintf('in o_fifo_read %d %d %d should all be the same', sz, rdcount, count));
end
end
function [avail] = o_fifo_avail(index)
global fifoCount fifoSamples fifoFiles fifoFids fifoDataType
avail = fifoSamples(index);
end
function index = o_fifo_new()
global fifoCount fifoSamples fifoFiles fifoFids fifoDataType
fifoCount = fifoCount + 1;
index = fifoCount;
fifoSamples(index) = 0;
fifoFiles{index} = tempname;
[ERR, MSG] = mkfifo(fifoFiles{index}, base2dec('744',8));
fifoFids(index) = fopen(fifoFiles{index}, 'a+');
% fcntl(fifoFids(index), F_SETFL, O_NONBLOCK); % uncomment to avoid hangs when trying to overfill fifo
end
% ---- usage -----
txfifo = o_fifo_new();
disp(o_fifo_avail(txfifo));
o_fifo_write(txfifo, [1.243 pi 2*pi 4/3*pi]');
disp(o_fifo_avail(txfifo));
disp(o_fifo_read(txfifo, 4));
disp(o_fifo_avail(txfifo));