Skip to content

Commit 30adb92

Browse files
authored
merge (#4)
* Update README.md * Create version.txt * Rename version.txt to currentversion.txt * Update issue templates * Update README.md Signed-off-by: Slash34 <90929320+Slashingbee@users.noreply.github.com> * Fixed typo in folder name, Renamed Ev3areo to Ev3Aero * Create stale.yml Signed-off-by: Slash34 <90929320+Slashingbee@users.noreply.github.com> * Create greetings.yml Signed-off-by: Slash34 <90929320+Slashingbee@users.noreply.github.com> * Update README.md Signed-off-by: Slash34 <90929320+Slashingbee@users.noreply.github.com> --------- Signed-off-by: Slash34 <90929320+Slashingbee@users.noreply.github.com>
1 parent f5792b3 commit 30adb92

File tree

10 files changed

+221
-97
lines changed

10 files changed

+221
-97
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
name: Bug report
3+
about: Create a report to help us improve
4+
title: ''
5+
labels: bug
6+
assignees: ''
7+
8+
---
9+
10+
**Describe the bug**
11+
A clear and concise description of what the bug is.
12+
13+
**To Reproduce**
14+
Steps to reproduce the behavior:
15+
1. Go to '...'
16+
2. Click on '....'
17+
3. Scroll down to '....'
18+
4. See error
19+
20+
**Expected behavior**
21+
A clear and concise description of what you expected to happen.
22+
23+
**Screenshots**
24+
If applicable, add screenshots to help explain your problem.
25+
26+
**Desktop (please complete the following information):**
27+
- OS: [e.g. iOS]
28+
- Browser [e.g. chrome, safari]
29+
- Version [e.g. 22]
30+
31+
**Smartphone (please complete the following information):**
32+
- Device: [e.g. iPhone6]
33+
- OS: [e.g. iOS8.1]
34+
- Browser [e.g. stock browser, safari]
35+
- Version [e.g. 22]
36+
37+
**Additional context**
38+
Add any other context about the problem here.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
name: Feature request
3+
about: Suggest an idea for this project
4+
title: ''
5+
labels: enhancement
6+
assignees: ''
7+
8+
---
9+
10+
**Is your feature request related to a problem? Please describe.**
11+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12+
13+
**Describe the solution you'd like**
14+
A clear and concise description of what you want to happen.
15+
16+
**Describe alternatives you've considered**
17+
A clear and concise description of any alternative solutions or features you've considered.
18+
19+
**Additional context**
20+
Add any other context or screenshots about the feature request here.

.github/ISSUE_TEMPLATE/question.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
name: Question
3+
about: Ask a question about the project, setup, or use cases.
4+
title: "[Question]"
5+
labels: help wanted, question
6+
assignees: ''
7+
8+
---
9+
10+
Topic:
11+
12+
13+
Tags:
14+
15+
16+
Detailed question:
17+
18+
19+
Hardware:

.github/workflows/greetings.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: Greetings
2+
3+
on: [pull_request_target, issues]
4+
5+
jobs:
6+
greeting:
7+
runs-on: ubuntu-latest
8+
permissions:
9+
issues: write
10+
pull-requests: write
11+
steps:
12+
- uses: actions/first-interaction@v1
13+
with:
14+
repo-token: ${{ secrets.GITHUB_TOKEN }}
15+
issue-message: "👋 Hi there! Welcome to the EV3Aero project — we're glad you're here! Thank you for opening your first issue. The ev3aero project is powered by the EV3Dev platform and community-driven innovation, so your feedback is really appreciated. One of the maintainers will review your report soon."
16+
pr-message: "Thank you for your first contribution to EV3Aero! We’re excited to see your pull request. The ev3aero project thrives on community support like yours, and we're grateful you're helping to improve it. A maintainer will review your changes soon."

.github/workflows/stale.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
2+
#
3+
# You can adjust the behavior by modifying this file.
4+
# For more information, see:
5+
# https://github.com/actions/stale
6+
name: Mark stale issues and pull requests
7+
8+
on:
9+
schedule:
10+
- cron: '0 3 * * *'
11+
12+
jobs:
13+
stale:
14+
15+
runs-on: ubuntu-latest
16+
permissions:
17+
issues: write
18+
pull-requests: write
19+
20+
steps:
21+
- uses: actions/stale@v5
22+
with:
23+
repo-token: ${{ secrets.GITHUB_TOKEN }}
24+
stale-issue-message: 'Stale issue message'
25+
stale-pr-message: 'Stale pull request message'
26+
stale-issue-label: 'no-issue-activity'
27+
stale-pr-label: 'no-pr-activity'
Lines changed: 97 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,97 @@
1-
import socket
2-
import pygame
3-
import sys
4-
import time
5-
import vgamepad as vg # Import vgamepad
6-
7-
def get_motor_positions(ip_address, port, retries=60, delay=0.5):
8-
"""Attempts to receive motor positions from the specified IP and port."""
9-
for attempt in range(retries):
10-
try:
11-
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
12-
s.connect((ip_address, port))
13-
data = s.recv(1024)
14-
received_str = data.decode()
15-
# Parse the motor positions and touch state
16-
pos_a_degrees = received_str.split(",")[0].split(":")[1].strip().split()[0]
17-
pos_b_degrees = received_str.split(",")[1].split(":")[1].strip().split()[0]
18-
pos_c_degrees = received_str.split(",")[2].split(":")[1].strip().split()[0]
19-
touch_state = received_str.split(",")[3].split(":")[1].strip()
20-
return pos_a_degrees, pos_b_degrees, pos_c_degrees, touch_state
21-
except (IndexError, ValueError, socket.error) as e:
22-
print(f"Error receiving motor positions (attempt {attempt + 1}/{retries}): {e}")
23-
time.sleep(delay)
24-
return "N/A", "N/A", "N/A", "N/A"
25-
26-
def main():
27-
ip_address = 'EV3-IP' # [LOCAL] IP of the device sending motor data (replaced random local ip with placeholder). (if using custom connection might not be needed)
28-
port = 12345 # Port to connect to (default port).
29-
30-
# Set limits for motor positions
31-
limit_a = 40
32-
limit_b = 45
33-
limit_c = 50
34-
35-
pygame.init()
36-
screen = pygame.display.set_mode((400, 300))
37-
pygame.display.set_caption('Motor Positions')
38-
font = pygame.font.Font(None, 36)
39-
clock = pygame.time.Clock()
40-
41-
# Initialize vGamepad (Xbox 360 Controller)
42-
gamepad = vg.VX360Gamepad()
43-
print("vGamepad initialized!")
44-
45-
while True:
46-
for event in pygame.event.get():
47-
if event.type == pygame.QUIT:
48-
pygame.quit()
49-
sys.exit()
50-
51-
pos_a_degrees, pos_b_degrees, pos_c_degrees, touch_state = get_motor_positions(ip_address, port)
52-
53-
if pos_a_degrees != "N/A":
54-
pos_a_degrees = max(min(float(pos_a_degrees), limit_a), -limit_a)
55-
if pos_b_degrees != "N/A":
56-
pos_b_degrees = max(min(float(pos_b_degrees), limit_b), -limit_b)
57-
if pos_c_degrees != "N/A":
58-
pos_c_degrees = max(min(float(pos_c_degrees), limit_c), -limit_c)
59-
60-
# Scale motor positions to joystick axis range (-32768 to 32767)
61-
scaled_pos_a = int((float(pos_a_degrees) / limit_a) * 32767)
62-
scaled_pos_b = int((float(pos_b_degrees) / limit_b) * 32767)
63-
64-
# Scale motor C to right joystick Y-axis (-32768 to 32767)
65-
if pos_c_degrees == "N/A":
66-
scaled_pos_c = 0 # Default to center if data is invalid
67-
else:
68-
scaled_pos_c = int((float(pos_c_degrees) / limit_c) * 32767)
69-
70-
# Send values to virtual gamepad
71-
gamepad.left_joystick(x_value=scaled_pos_a, y_value=scaled_pos_b) # Left joystick
72-
gamepad.right_joystick(x_value=0, y_value=scaled_pos_c) # Right joystick Y-axis
73-
74-
# Set button state
75-
if touch_state == "1":
76-
gamepad.press_button(vg.XUSB_BUTTON.XUSB_GAMEPAD_A)
77-
else:
78-
gamepad.release_button(vg.XUSB_BUTTON.XUSB_GAMEPAD_A)
79-
80-
gamepad.update() # Apply changes to virtual controller
81-
82-
# Display motor positions on screen
83-
screen.fill((255, 255, 255))
84-
text_a = font.render(f"Motor A Position: {pos_a_degrees} degrees", True, (0, 0, 0))
85-
text_b = font.render(f"Motor B Position: {pos_b_degrees} degrees", True, (0, 0, 0))
86-
text_c = font.render(f"Motor C Position: {pos_c_degrees} degrees", True, (0, 0, 0))
87-
text_touch = font.render(f"Button State: {touch_state}", True, (0, 0, 0))
88-
screen.blit(text_a, (20, 50))
89-
screen.blit(text_b, (20, 100))
90-
screen.blit(text_c, (20, 150))
91-
screen.blit(text_touch, (20, 200))
92-
93-
pygame.display.flip()
94-
clock.tick(1000) # Update every 1 millisecond
95-
96-
if __name__ == "__main__":
97-
main()
1+
import socket
2+
import pygame
3+
import sys
4+
import time
5+
import vgamepad as vg # Import vgamepad
6+
7+
def get_motor_positions(ip_address, port, retries=60, delay=0.5):
8+
"""Attempts to receive motor positions from the specified IP and port."""
9+
for attempt in range(retries):
10+
try:
11+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
12+
s.connect((ip_address, port))
13+
data = s.recv(1024)
14+
received_str = data.decode()
15+
# Parse the motor positions and touch state
16+
pos_a_degrees = received_str.split(",")[0].split(":")[1].strip().split()[0]
17+
pos_b_degrees = received_str.split(",")[1].split(":")[1].strip().split()[0]
18+
pos_c_degrees = received_str.split(",")[2].split(":")[1].strip().split()[0]
19+
touch_state = received_str.split(",")[3].split(":")[1].strip()
20+
return pos_a_degrees, pos_b_degrees, pos_c_degrees, touch_state
21+
except (IndexError, ValueError, socket.error) as e:
22+
print(f"Error receiving motor positions (attempt {attempt + 1}/{retries}): {e}")
23+
time.sleep(delay)
24+
return "N/A", "N/A", "N/A", "N/A"
25+
26+
def main():
27+
ip_address = 'EV3-IP' # [LOCAL] IP of the device sending motor data (replaced random local ip with placeholder). (if using custom connection might not be needed)
28+
port = 12345 # Port to connect to (default port).
29+
30+
# Set limits for motor positions
31+
limit_a = 40
32+
limit_b = 45
33+
limit_c = 50
34+
35+
pygame.init()
36+
screen = pygame.display.set_mode((400, 300))
37+
pygame.display.set_caption('Motor Positions')
38+
font = pygame.font.Font(None, 36)
39+
clock = pygame.time.Clock()
40+
41+
# Initialize vGamepad (Xbox 360 Controller)
42+
gamepad = vg.VX360Gamepad()
43+
print("vGamepad initialized!")
44+
45+
while True:
46+
for event in pygame.event.get():
47+
if event.type == pygame.QUIT:
48+
pygame.quit()
49+
sys.exit()
50+
51+
pos_a_degrees, pos_b_degrees, pos_c_degrees, touch_state = get_motor_positions(ip_address, port)
52+
53+
if pos_a_degrees != "N/A":
54+
pos_a_degrees = max(min(float(pos_a_degrees), limit_a), -limit_a)
55+
if pos_b_degrees != "N/A":
56+
pos_b_degrees = max(min(float(pos_b_degrees), limit_b), -limit_b)
57+
if pos_c_degrees != "N/A":
58+
pos_c_degrees = max(min(float(pos_c_degrees), limit_c), -limit_c)
59+
60+
# Scale motor positions to joystick axis range (-32768 to 32767)
61+
scaled_pos_a = int((float(pos_a_degrees) / limit_a) * 32767)
62+
scaled_pos_b = int((float(pos_b_degrees) / limit_b) * 32767)
63+
64+
# Scale motor C to right joystick Y-axis (-32768 to 32767)
65+
if pos_c_degrees == "N/A":
66+
scaled_pos_c = 0 # Default to center if data is invalid
67+
else:
68+
scaled_pos_c = int((float(pos_c_degrees) / limit_c) * 32767)
69+
70+
# Send values to virtual gamepad
71+
gamepad.left_joystick(x_value=scaled_pos_a, y_value=scaled_pos_b) # Left joystick
72+
gamepad.right_joystick(x_value=0, y_value=scaled_pos_c) # Right joystick Y-axis
73+
74+
# Set button state
75+
if touch_state == "1":
76+
gamepad.press_button(vg.XUSB_BUTTON.XUSB_GAMEPAD_A)
77+
else:
78+
gamepad.release_button(vg.XUSB_BUTTON.XUSB_GAMEPAD_A)
79+
80+
gamepad.update() # Apply changes to virtual controller
81+
82+
# Display motor positions on screen
83+
screen.fill((255, 255, 255))
84+
text_a = font.render(f"Motor A Position: {pos_a_degrees} degrees", True, (0, 0, 0))
85+
text_b = font.render(f"Motor B Position: {pos_b_degrees} degrees", True, (0, 0, 0))
86+
text_c = font.render(f"Motor C Position: {pos_c_degrees} degrees", True, (0, 0, 0))
87+
text_touch = font.render(f"Button State: {touch_state}", True, (0, 0, 0))
88+
screen.blit(text_a, (20, 50))
89+
screen.blit(text_b, (20, 100))
90+
screen.blit(text_c, (20, 150))
91+
screen.blit(text_touch, (20, 200))
92+
93+
pygame.display.flip()
94+
clock.tick(1000) # Update every 1 millisecond
95+
96+
if __name__ == "__main__":
97+
main()

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ python main.py
113113
- Note the license of the following project is important when u want to make edit's or make your own version public. Private projects aren't taken into account.
114114
- The prototype version's dont have requirement file's (yet) so you have to download package's manually using PyPI (PIP).
115115
- More info on the version's is in the version.md file
116+
- The install guide is only gonna work on the main release, other version's **DO NOT HAVE INSTALL GUIDES** as they install differently and require manual installation!
117+
- Check the help wanted tag if you want to contribute and do not have idea's what to improve, there is propably task's there.
116118
---
117119
## Mentions
118120

@@ -132,3 +134,4 @@ python main.py
132134
A Java-based replacement firmware for LEGO Mindstorms, foundational for early programmable robot systems.
133135

134136
---
137+
Note: The client-side (EV3) runs on ev3dev and does not support external Python dependencies — all code is designed to run using built-in libraries only.

currentversion.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is the release version (VER 1.0.0.0) [main].

0 commit comments

Comments
 (0)