VHDL PS/2 interface - interface

I am using VHDL and an FPGA board, a VGA interface and a PS/2 keyboard interface to create a maze and make a square that can move through the maze. When I press one of the keys (WASD), the square moves only one position and then will not move again. I need it to move every time one of the keys is pressed. Here is my code:
ENTITY hw_image_generator IS
PORT(
ps2_code : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
game_clk : IN STD_LOGIC;
disp_ena : IN STD_LOGIC; --display enable ('1' = display time, '0' = blanking time)
row : IN INTEGER; --row pixel coordinate
column : IN INTEGER; --column pixel coordinate
red : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0'); --red magnitude output to DAC
green : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0'); --green magnitude output to DAC
blue : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0')); --blue magnitude output to DAC
END hw_image_generator;
ARCHITECTURE behavior OF hw_image_generator IS
signal x_position: INTEGER := 20;
signal y_position: INTEGER := 20;
CONSTANT max_count: NATURAL := 500000;
SIGNAL reset: STD_LOGIC;
BEGIN
PROCESS(game_clk, reset, x_position, y_position)
VARIABLE count : NATURAL range 0 to max_count;
BEGIN
IF (reset = '1') THEN
count := 0;
x_position <= 20;
y_position <= 20;
ELSIF(rising_edge(game_clk) AND count = 0) THEN
IF(count < max_count)THEN
IF(ps2_code = "00101001") THEN -- space bar
count := 0;
x_position <= 20;
y_position <= 20;
END IF;
IF(ps2_code = "00011101") THEN --W key
count := count + 1;
y_position <= y_position;
x_position <= x_position - 10;
END IF;
IF(ps2_code = "00011011") THEN --S key
count := count + 1;
y_position <= y_position;
x_position <= x_position + 10;
END IF;
IF(ps2_code = "00100011") THEN --D key
count := count + 1;
x_position <= x_position;
y_position <= y_position + 10;
END IF;
IF(ps2_code = "00011100") THEN --A key
count := count + 1;
x_position <= x_position;
y_position <= y_position - 10;
END IF;
ELSE
count := 0;
END IF;
END IF;
END PROCESS;
PROCESS(disp_ena, row, column)
BEGIN
IF(disp_ena = '1') THEN --display time
IF(row < 512 AND column > 231 AND column < 281) THEN
red <= (OTHERS => '0');
green <= (OTHERS => '0');
blue <= (OTHERS => '0');
ELSIF(row > 743 AND row < 793 AND column < 512) THEN
red <= (OTHERS => '0');
green <= (OTHERS => '0');
blue <= (OTHERS => '0');
ELSIF(row > 1024 AND column > 231 AND column < 281) THEN
red <= (OTHERS => '0');
green <= (OTHERS => '0');
blue <= (OTHERS => '0');
ELSIF(row > 256 AND row < 1024 AND column > 487 AND column < 537) THEN
red <= (OTHERS => '0');
green <= (OTHERS => '0');
blue <= (OTHERS => '0');
ELSIF(row > 487 AND row < 537 AND column > 536 AND column < 768) THEN
red <= (OTHERS => '0');
green <= (OTHERS => '0');
blue <= (OTHERS => '0');
ELSIF(row > 231 AND row < 281 AND column > 768) THEN
red <= (OTHERS => '0');
green <= (OTHERS => '0');
blue <= (OTHERS => '0');
ELSIF(row > 743 AND row < 793 AND column > 768) THEN
red <= (OTHERS => '0');
green <= (OTHERS => '0');
blue <= (OTHERS => '0');
ELSIF(row > 974 AND row < 1024 AND column > 536 AND column < 768) THEN
red <= (OTHERS => '0');
green <= (OTHERS => '0');
blue <= (OTHERS => '0');
ELSE
red <= (OTHERS => '1');
green <= (OTHERS => '1');
blue <= (OTHERS => '1');
END IF;
IF(row > x_position AND row < x_position+50 AND column > y_position AND column < y_position+50) THEN
red <= (OTHERS => '1');
green <= (OTHERS => '0');
blue <= (OTHERS => '0');
END IF;
ELSE --blanking time
red <= (OTHERS => '0');
green <= (OTHERS => '0');
blue <= (OTHERS => '0');
END IF;
END PROCESS;
END behavior;

In your unlabelled process sensitive to game_clk:
process (game_clk, reset, x_position, y_position)
variable count: natural range 0 to max_count;
begin
if reset = '1' then
count := 0;
x_position <= 20;
y_position <= 20;
elsif rising_edge(game_clk) and count = 0 then
if count < max_count then
if ps2_code = "00101001" then -- space bar
count := 0;
x_position <= 20;
y_position <= 20;
end if;
if ps2_code = "00011101" then --w key
count := count + 1;
y_position <= y_position;
x_position <= x_position - 10;
end if;
if ps2_code = "00011011" then --s key
count := count + 1;
y_position <= y_position;
x_position <= x_position + 10;
end if;
if ps2_code = "00100011" then --d key
count := count + 1;
x_position <= x_position;
y_position <= y_position + 10;
end if;
if ps2_code = "00011100" then --a key
count := count + 1;
x_position <= x_position;
y_position <= y_position - 10;
end if;
else
count := 0;
end if;
end if;
end process;
Notice you don't need x_position and y_position in the sensitivity list. All signal assignments are either due to a reset event or a game_clk event.
Also note the enable count = 0 in the condition for the elsif:
elsif rising_edge(game_clk) and count = 0 then
And the condition in the following if statement:
if count < max_count then
Once any of your ps2_code recognizers (except the space bar) is valid you'll increment count and no longer enable any flip flops and registers you're assigning here on the rising edge of game_clk. You also can't tell if you hit successive space bars. without hitting another recognizer.
Your code matches your description of your problem, it's a feature.

PROCESS(game_clk)
BEGIN
IF(game_clk'EVENT AND game_clk = '1')THEN
count <= count + 1;
IF(count = 5000000 AND ps2_code = "00101001")THEN --space key
count <= 0;
x_position <= 20;
y_position <= 20;
END IF;
IF(count = 5000000 AND ps2_code = "00011101")THEN --W key
count <= 0;
IF((y_position > 0 AND y_position < 181 AND x_position > 0 and x_position < 512) --1
OR (y_position > 0 AND y_position < 437 AND x_position > 512 AND x_position < 693) --2
OR (y_position > 281 AND y_position < 437 AND x_position > 0 and x_position < 512) --3
OR (y_position > 437 AND y_position < 537 AND x_position > 0 AND x_position < 206) --4
OR (y_position > 537 AND y_position < 1227 AND x_position > 0 AND x_position < 181) --5
OR (y_position > 537 AND y_position < 718 AND x_position > 181 AND x_position < 437) --6
OR (y_position > 768 AND y_position < 1227 AND x_position > 281 AND x_position < 718) --7
OR (y_position > 537 AND y_position < 768 AND x_position > 537 AND x_position < 693) --8
OR (y_position > 537 AND y_position < 718 AND x_position > 693 AND x_position < 793) --9
OR (y_position > 537 AND y_position < 768 AND x_position > 793 AND x_position < 975) --10
OR (y_position > 768 AND y_position < 1227 AND x_position > 793 AND x_position < 1027) --11
OR (y_position > 718 AND y_position < 768 AND x_position > 281 AND x_position < 437) --12
) THEN
x_position <= x_position - 10;
ELSE
x_position <= x_position + 5;
y_position <= y_position;
END IF;
ELSIF(count = 5000000 AND ps2_code = "00011011") THEN --S key
count <= 0;
IF((y_position > 0 AND y_position < 181 AND x_position > 0 and x_position < 512) --1
OR (y_position > 0 AND y_position < 437 AND x_position > 512 AND x_position < 693) --2
OR (y_position > 281 AND y_position < 437 AND x_position > 0 and x_position < 512) --3
OR (y_position > 437 AND y_position < 537 AND x_position > 0 AND x_position < 206) --4
OR (y_position > 537 AND y_position < 1227 AND x_position > 0 AND x_position < 181) --5
OR (y_position > 537 AND y_position < 718 AND x_position > 181 AND x_position < 437) --6
OR (y_position > 768 AND y_position < 1227 AND x_position > 281 AND x_position < 718) --7
OR (y_position > 537 AND y_position < 768 AND x_position > 537 AND x_position < 693) --8
OR (y_position > 537 AND y_position < 718 AND x_position > 693 AND x_position < 793) --9
OR (y_position > 537 AND y_position < 768 AND x_position > 793 AND x_position < 975) --10
OR (y_position > 768 AND y_position < 1227 AND x_position > 793 AND x_position < 1027) --11
OR (y_position > 718 AND y_position < 768 AND x_position > 281 AND x_position < 437) --12
) THEN
x_position <= x_position + 10;
ELSE
x_position <= x_position - 5;
y_position <= y_position;
END IF;
ELSIF(count = 5000000 AND ps2_code = "00100011") THEN --D key
count <= 0;
IF((y_position > 0 AND y_position < 181 AND x_position > 0 and x_position < 512) --1
OR (y_position > 0 AND y_position < 437 AND x_position > 512 AND x_position < 693) --2
OR (y_position > 281 AND y_position < 437 AND x_position > 0 and x_position < 512) --3
OR (y_position > 437 AND y_position < 537 AND x_position > 0 AND x_position < 206) --4
OR (y_position > 537 AND y_position < 1227 AND x_position > 0 AND x_position < 181) --5
OR (y_position > 537 AND y_position < 718 AND x_position > 181 AND x_position < 437) --6
OR (y_position > 768 AND y_position < 1227 AND x_position > 281 AND x_position < 718) --7
OR (y_position > 537 AND y_position < 768 AND x_position > 537 AND x_position < 693) --8
OR (y_position > 537 AND y_position < 718 AND x_position > 693 AND x_position < 793) --9
OR (y_position > 537 AND y_position < 768 AND x_position > 793 AND x_position < 975) --10
OR (y_position > 768 AND y_position < 1227 AND x_position > 793 AND x_position < 1027) --11
OR (y_position > 718 AND y_position < 768 AND x_position > 281 AND x_position < 437) --12
) THEN
y_position <= y_position + 10;
ELSE
x_position <= x_position;
y_position <= y_position -5;
END IF;
ELSIF(count = 5000000 AND ps2_code = "00011100") THEN --A key
count <= 0;
IF((y_position > 0 AND y_position < 181 AND x_position > 0 and x_position < 512) --1
OR (y_position > 0 AND y_position < 437 AND x_position > 512 AND x_position < 693) --2
OR (y_position > 281 AND y_position < 437 AND x_position > 0 and x_position < 512) --3
OR (y_position > 437 AND y_position < 537 AND x_position > 0 AND x_position < 206) --4
OR (y_position > 537 AND y_position < 1227 AND x_position > 0 AND x_position < 181) --5
OR (y_position > 537 AND y_position < 718 AND x_position > 181 AND x_position < 437) --6
OR (y_position > 768 AND y_position < 1227 AND x_position > 281 AND x_position < 718) --7
OR (y_position > 537 AND y_position < 768 AND x_position > 537 AND x_position < 693) --8
OR (y_position > 537 AND y_position < 718 AND x_position > 693 AND x_position < 793) --9
OR (y_position > 537 AND y_position < 768 AND x_position > 793 AND x_position < 975) --10
OR (y_position > 768 AND y_position < 1227 AND x_position > 793 AND x_position < 1027) --11
OR (y_position > 718 AND y_position < 768 AND x_position > 281 AND x_position < 437) --12
) THEN
y_position <= y_position - 10;
ELSE
x_position <= x_position;
y_position <= y_position +5;
END IF;
END IF;
END IF;
END PROCESS;

Related

How to store packet offset in BPF Map or skb->cb field?

Example Code
I want to pass the offset to the following tail calls. But when I try to store it in BPF MAP(Method 1) or skb->cb field(Method 2), I get an error offset is outside of the packet.
If Method 1/2 code is removed, the bpf program can be loaded sucessfully.
#include <vmlinux.h>
#include <bpf/bpf_endian.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
struct {
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
__type(key, __u32);
__type(value, __u32);
__uint(max_entries, 100);
} state_vars SEC(".maps");
SEC("tc")
int tc_ingress(struct __sk_buff *ctx) {
void *data_end = (void *)(__u64)ctx->data_end;
void *data = (void *)(__u64)ctx->data;
u32 data_len = data_end - data;
u32 rn = 0;
u32 rn_idx = 0;
for (rn = 0; rn < 1000 && rn < data_len && data + rn < data_end; rn++) {
char c = *(char*)(data + rn);
if (c == '\r') {
rn_idx = rn;
break;
}
}
/// Method 1
// u32 var_idx = 0;
// bpf_map_update_elem(&state_vars, &var_idx, &rn_idx, BPF_ANY);
/// Method 2
// ctx->cb[0] = rn_idx;
return TC_ACT_OK;
}
Error Message
Method 1
; void *data = (void *)(__u64)ctx->data;
0: (61) r2 = *(u32 *)(r1 +76)
; void *data_end = (void *)(__u64)ctx->data_end;
1: (61) r3 = *(u32 *)(r1 +80)
2: (b7) r1 = 0
; u32 rn_idx = 0;
3: (63) *(u32 *)(r10 -4) = r1
last_idx 3 first_idx 0
regs=2 stack=0 before 2: (b7) r1 = 0
; u32 data_len = data_end - data;
4: (bf) r4 = r3
5: (1f) r4 -= r2
6: (67) r4 <<= 32
7: (77) r4 >>= 32
; for (rn = 0; rn < 1000 && rn < data_len && data + rn < data_end; rn++) {
8: (15) if r4 == 0x0 goto pc+10
R1_w=invP0 R2_w=pkt(id=0,off=0,r=0,imm=0) R3_w=pkt_end(id=0,off=0,imm=0) R4_w=inv(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R10=fp0 fp-8=0000????
; for (rn = 0; rn < 1000 && rn < data_len && data + rn < data_end; rn++) {
9: (bf) r5 = r2
10: (0f) r5 += r1
; for (rn = 0; rn < 1000 && rn < data_len && data + rn < data_end; rn++) {
11: (3d) if r5 >= r3 goto pc+7
R1_w=invP0 R2_w=pkt(id=0,off=0,r=0,imm=0) R3_w=pkt_end(id=0,off=0,imm=0) R4_w=inv(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R5_w=pkt(id=0,off=0,r=0,imm=0) R10=fp0 fp-8=0000????
; char c = *(char*)(data + rn);
12: (71) r5 = *(u8 *)(r5 +0)
invalid access to packet, off=0 size=1, R5(id=0,off=0,r=0)
R5 offset is outside of the packet
processed 13 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
Method 2
; void *data = (void *)(__u64)ctx->data;
1: (61) r3 = *(u32 *)(r1 +76)
; void *data_end = (void *)(__u64)ctx->data_end;
2: (61) r4 = *(u32 *)(r1 +80)
; u32 data_len = data_end - data;
3: (bf) r5 = r4
4: (1f) r5 -= r3
5: (bf) r0 = r5
6: (67) r0 <<= 32
7: (77) r0 >>= 32
; for (rn = 0; rn < 1000 && rn < data_len && data + rn < data_end; rn++) {
8: (15) if r0 == 0x0 goto pc+21
R0_w=inv(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R1=ctx(id=0,off=0,imm=0) R2_w=inv0 R3_w=pkt(id=0,off=0,r=0,imm=0) R4_w=pkt_end(id=0,off=0,imm=0) R5_w=inv(id=0) R10=fp0
9: (b7) r2 = 0
10: (b7) r0 = 0
; for (rn = 0; rn < 1000 && rn < data_len && data + rn < data_end; rn++) {
11: (bf) r6 = r3
12: (0f) r6 += r0
last_idx 12 first_idx 0
regs=1 stack=0 before 11: (bf) r6 = r3
regs=1 stack=0 before 10: (b7) r0 = 0
; for (rn = 0; rn < 1000 && rn < data_len && data + rn < data_end; rn++) {
13: (3d) if r6 >= r4 goto pc+16
R0_w=invP0 R1=ctx(id=0,off=0,imm=0) R2_w=inv0 R3_w=pkt(id=0,off=0,r=0,imm=0) R4_w=pkt_end(id=0,off=0,imm=0) R5_w=inv(id=0) R6_w=pkt(id=0,off=0,r=0,imm=0) R10=fp0
; char c = *(char*)(data + rn);
14: (71) r6 = *(u8 *)(r6 +0)
invalid access to packet, off=0 size=1, R6(id=0,off=0,r=0)
R6 offset is outside of the packet
processed 15 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
Question
Why does the error appear when Method 1/2 code is added?
How could I store the offset value in BPF MAP or skb->cb field?
Update 2022.11.1
follow #pchaigno's advice, add +1 in the condition, I get similar error:
; int tc_ingress(struct __sk_buff *ctx)
0: (b7) r2 = 0
; void *data = (void *)(__u64)ctx->data;
1: (61) r3 = *(u32 *)(r1 +76)
; void *data_end = (void *)(__u64)ctx->data_end;
2: (61) r4 = *(u32 *)(r1 +80)
; u32 data_len = data_end - data;
3: (bf) r5 = r4
4: (1f) r5 -= r3
5: (bf) r0 = r5
6: (67) r0 <<= 32
7: (77) r0 >>= 32
; for (rn = 0; rn < 1000 && rn < data_len && data + rn + 1 < data_end; rn++) {
8: (15) if r0 == 0x0 goto pc+23
R0_w=inv(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R1=ctx(id=0,off=0,imm=0) R2_w=inv0 R3_w=pkt(id=0,off=0,r=0,imm=0) R4_w=pkt_end(id=0,off=0,imm=0) R5_w=inv(id=0) R10=fp0
9: (b7) r2 = 0
10: (b7) r0 = 0
; for (rn = 0; rn < 1000 && rn < data_len && data + rn + 1 < data_end; rn++) {
11: (bf) r6 = r3
12: (0f) r6 += r0
last_idx 12 first_idx 0
regs=1 stack=0 before 11: (bf) r6 = r3
regs=1 stack=0 before 10: (b7) r0 = 0
13: (bf) r7 = r6
14: (07) r7 += 1
; for (rn = 0; rn < 1000 && rn < data_len && data + rn + 1 < data_end; rn++) {
15: (3d) if r7 >= r4 goto pc+16
R0_w=invP0 R1=ctx(id=0,off=0,imm=0) R2_w=inv0 R3_w=pkt(id=0,off=0,r=0,imm=0) R4_w=pkt_end(id=0,off=0,imm=0) R5_w=inv(id=0) R6_w=pkt(id=0,off=0,r=0,imm=0) R7_w=pkt(id=0,off=1,r=0,imm=0) R10=fp0
; char c = *(char*)(data + rn);
16: (71) r6 = *(u8 *)(r6 +0)
invalid access to packet, off=0 size=1, R6(id=0,off=0,r=0)
R6 offset is outside of the packet
processed 17 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
TL;DR. The issue is when you read the packet data, not when you write it. You have an off-by-one issue on the bounds check. The issue only appears once you use the read data because otherwise the compiler optimizes out the code.
Verifier Error Explanation
; for (rn = 0; rn < 1000 && rn < data_len && data + rn < data_end; rn++) {
11: (3d) if r5 >= r3 goto pc+7
R1_w=invP0 R2_w=pkt(id=0,off=0,r=0,imm=0) R3_w=pkt_end(id=0,off=0,imm=0) R4_w=inv(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R5_w=pkt(id=0,off=0,r=0,imm=0) R10=fp0 fp-8=0000????
; char c = *(char*)(data + rn);
12: (71) r5 = *(u8 *)(r5 +0)
invalid access to packet, off=0 size=1, R5(id=0,off=0,r=0)
The verifier says that that the packet access is out of bounds by one: R5's offset + size > R3's offset. That is, both offsets are 0 and the access size is 1.
Root Cause
Your bounds check is off by one:
for (rn = 0; rn < 1000 && rn < data_len && data + rn < data_end; rn++) {
char c = *(char*)(data + rn);
To account for the access size, it should be:
for (rn = 0; rn < 1000 && rn < data_len && data + rn + 1 < data_end; rn++) {
char c = *(char*)(data + rn);
Why does it only happen once you write the packet data?
If you don't write rn_idx anywhere, then the compiler understands that rn_idx and c are not needed. All code for those variables is compiled out and the out-of-bound packet access is removed.

how to stop adding 1 to a variable when it reaches 11?

out = 0
def catchoutp2():
global out
x = random.randint(1, 100)
if x > 60:
out += 1
I want to stop adding when out reaches 11
Just add a condition that x > 60 and out < 12. Won't that work?
if x > 60 and out < 12:

how to select wanted ( needed situations) dual elements which are randomly generated by using random sampling in matlab?

I have 2 different random selected variables. The first one is number of bedrooms which is r1 and the second one is number of people in the dwelling which is r2. there are different certain constant values, which are going to be used for selection of house size.Wanted combinations
There are 24 different combinations that both of random generators can produce by using number of bedrooms and number of people in the house. there is no problem if the random generators produce wanted combinations.If not, there is a problem come out which is unwanted combinations.
How can get rid of this unwanted combinations or how to solve this problem in another way?
My code is as follows:
R1 = randsample('xyzq',1,true,[0.1 0.2 0.43 0.27]); % Probability of number of bedrooms in dwellings
r1=R1;
R2 = randsample('abcdef',1,true,[0.283 0.358 0.163 0.134 0.044 0.018]); %Probability of Household size in UK
r2=R2;
if (r1 == 'x' && r2 == 'a') % 37m2 1 bed, 1 per
A_roof = 37;
A_floor = 37;
A_wall = 35;
A_door = 3;
A_windows = 3;
elseif (r1 == 'x' && r2 == 'b') % 50m2 1 bed, 2 per
A_roof = 50;
A_floor = 50;
A_wall = 47;
A_door = 6;
A_windows = 6;
elseif (r1 == 'y' && r2 == 'c') % 61m2 2 bed, 3 per
A_roof = 61;
A_floor = 61;
A_wall = 42;
A_door = 5;
A_windows = 5;
elseif (r1 == 'y' && r2 == 'd') % 70m2 2 bed, 4 per
A_roof = 70;
A_floor = 70;
A_wall = 50;
A_door = 5;
A_windows = 5;
elseif (r1 == 'y' && r2 == 'd') % 74m2 3 bed, 4 per
A_roof = 74;
A_floor = 74;
A_wall = 51;
A_door = 6;
A_windows = 6;
elseif (r1 == 'z' && r2 == 'e') % 86m2 3 bed, 5 per
A_roof = 86;
A_floor = 86;
A_wall = 55;
A_door = 6;
A_windows = 6;
elseif (r1 == 'z' && r2 == 'f') % 95m2 3 bed, 6 per
A_roof = 95;
A_floor = 95;
A_wall = 70;
A_door = 7;
A_windows = 7;
elseif (r1 == 'q' && r2 == 'e') % 90m2 4 bed, 5 per
A_roof = 90;
A_floor = 90;
A_wall = 68;
A_door = 7;
A_windows = 7;
elseif (r1 == 'q' && r2 == 'f') % 99m2 4 bed, 6 per
A_roof = 99;
A_floor = 99;
A_wall = 74;
A_door = 8;
A_windows = 8;
elseif (r1 == 'y' && r2 == 'd') % 83m2 2 bed, 4 per
A_roof = 40;
A_floor = 83;
A_wall = 105;
A_door = 8;
A_windows = 8;
elseif (r1 == 'z') && (r2 == 'd') % 87m2 3 bed, 4 per
A_roof = 42;
A_floor = 87;
A_wall = 105;
A_door = 8;
A_windows = 8;
elseif (r1 == 'z' && r2 == 'e') % 96m2 3 bed, 5 per
A_roof = 46;
A_floor = 96;
A_wall = 150;
A_door = 10;
A_windows = 10;
elseif (r1 == 'q' && r2 == 'e') % 100m2 4 bed, 5 per
A_roof = 50;
A_floor = 100;
A_wall = 180;
A_door = 10;
A_windows = 10;
elseif(r1 == 'q' && r2 == 'f') % 107m2 4 bed, 6 per
A_roof = 55;
A_floor = 107;
A_wall = 125;
A_door = 10;
A_windows = 10;
elseif (r1 == 'z' && r2 == 'e') % 102m2 3 bed, 5 per
A_roof = 50;
A_floor = 102;
A_wall = 200;
A_door = 10;
A_windows = 10;
elseif (r1 == 'q' && r2 == 'e') % 106m2 4 bed, 5 per
A_roof = 55;
A_floor = 106;
A_wall = 200;
A_door = 10;
A_windows = 10;
elseif (r1 == 'q' && r2 == 'f') % 113m2 4 bed, 6 per
A_roof = 60;
A_floor = 113;
A_wall = 200;
A_door = 10;
A_windows = 10;
end

How to specify a range and perform a function accordingly in matlab?

I need to perform the following function in matlab.
I had tried the following code but somehow my if statement is wrong. I'd like to know how to use the if statement efficiently here. If there is any other method in which i could perform the function please do help. My code is as follows
if (y(i,j) < -0.5, y(i,j) >= -1)
f(i,j) = 0
elseif (y(i,j) < 0, y(i,j) >= -0.5)
f(i,j) = 1
elseif (y(i,j) < 0.75, y(i,j) >= 0)
f(i,j) = 2
elseif (y(i,j) < 1, y(i,j) >= 0.75)
f(i,j) = 3
end
Here y(i,j) is a 1 x 256 matrix. Thanks
You need to use the logical AND operator to tie two Boolean expressions together. You are using a comma which is not correct:
if (y(i,j) < -0.5 && y(i,j) >= -1)
f(i,j) = 0
elseif (y(i,j) < 0 && y(i,j) >= -0.5)
f(i,j) = 1
elseif (y(i,j) < 0.75 && y(i,j) >= 0)
f(i,j) = 2
elseif (y(i,j) < 1 && y(i,j) >= 0.75)
f(i,j) = 3
end
However, it looks like you're using this in a for loop and I wouldn't perform the above in a loop. Use logical indexing instead:
f(y < -0.5 & y >= 1) = 0;
f(y < 0 & y >= -0.5) = 1;
f(y < 0.75 & y >= 0) = 2;
f(y < 1 & y >= 0.75) = 3;
This is assuming that f is the same size as y.

Linear Impulses - Cocos2d/Objective-C/Box2d

I have a cannon, a ball, and a trigger. When you press the trigger a linear impulse is applied to the ball.
short int direction = [level.cannon cannon].rotation;
short int power = 24.8;
b2Vec2 force = b2Vec2(direction, power);
[level.ball body]->ApplyLinearImpulse(force, [level.ball body]->GetWorldCenter());
My problem is, when the trigger is pressed, the linear impulse is applied to the ball, but the ball doesn't actually come out of the top of the cannon sprite.
The reason it is doing this (I think) is because I have set the anchor point, for the cannon, to (0.5, 0).
cannon.anchorPoint = ccp(0.5, 0);
I have figured out that for every 5 degrees the cannon rotates, a multiple of 2 needs to be added/subtracted to the rotation.
E.G.
For 0 to 55 Degrees
0 to 5 subtract 2 from the rotation
5 to 10 subtract 4 from the rotation
10 to 15 subtract 6 from the rotation
etc.
For 0 to -55 Degrees
0 to -5 add 2 to the rotation
-5 to -10 add 4 to the rotation
-10 to -15 add 6 to the rotation
Currently, I am using this code to accomplish this.
if (_cannon.rotation == 0)
{
direction = _cannon.rotation;
} else if (_cannon.rotation >= 1 && _cannon.rotation < 6)
{
direction = _cannon.rotation - 2;
} else if (_cannon.rotation >= 6 && _cannon.rotation < 11)
{
direction = _cannon.rotation - 4;
} else if (_cannon.rotation >= 11 && _cannon.rotation < 16)
{
direction = _cannon.rotation - 6;
} else if (_cannon.rotation >= 16 && _cannon.rotation < 21)
{
direction = _cannon.rotation - 8;
} else if (_cannon.rotation >= 21 && _cannon.rotation < 26)
{
direction = _cannon.rotation - 10;
} else if (_cannon.rotation >= 26 && _cannon.rotation < 31)
{
direction = _cannon.rotation - 12;
} else if (_cannon.rotation >= 31 && _cannon.rotation < 36)
{
direction = _cannon.rotation - 14;
} else if (_cannon.rotation >= 36 && _cannon.rotation < 41)
{
direction = _cannon.rotation - 16;
} else if (_cannon.rotation >= 41 && _cannon.rotation < 46)
{
direction = _cannon.rotation - 18;
} else if (_cannon.rotation >= 46 && _cannon.rotation < 55)
{
direction = _cannon.rotation - 20;
} else if (_cannon.rotation <= -1 && _cannon.rotation > -6)
{
direction = _cannon.rotation + 2;
} else if (_cannon.rotation <= -6 && _cannon.rotation > -11)
{
direction = _cannon.rotation + 4;
} else if (_cannon.rotation <= -11 && _cannon.rotation > -16)
{
direction = _cannon.rotation + 6;
} else if (_cannon.rotation <= -16 && _cannon.rotation > -21)
{
direction = _cannon.rotation + 8;
} else if (_cannon.rotation <= -21 && _cannon.rotation > -26)
{
direction = _cannon.rotation + 10;
} else if (_cannon.rotation <= -26 && _cannon.rotation > -31)
{
direction = _cannon.rotation + 12;
} else if (_cannon.rotation <= -31 && _cannon.rotation > -36)
{
direction = _cannon.rotation + 14;
} else if (_cannon.rotation <= -36 && _cannon.rotation > -41)
{
direction = _cannon.rotation + 16;
} else if (_cannon.rotation <= -41 && _cannon.rotation > -46)
{
direction = _cannon.rotation + 18;
} else if (_cannon.rotation <= -46 && _cannon.rotation > -55)
{
direction = _cannon.rotation + 20;
}
I know there has to be an easier way to do this, but I'm still learning. Can someone please help me?
short int val, val2;
val = _cannon.rotation/5;
val2 = _cannon.rotation%5; //remainder of the division
//it will be zero when rotation is a multiple of 5.
if(val2 > 0)
val += 1;
direction = _cannon.rotation - 2*val;
I'm not sure if this is what you want, and I didn't test it. Just made some mental tests to see if it works for the cases you put.
But I hope you can use this as a starting point for making your code smaller.