Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Script feature #14

Merged
merged 29 commits into from
Apr 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
3228003
Script feature beta
leotrj Mar 20, 2017
c60a1ff
Added STOP and SETWHEELS
leotrj Mar 20, 2017
5ace756
Added STOP and SETWHEELS
leotrj Mar 20, 2017
7d84d32
Improved Script implementation
leotrj Mar 22, 2017
f8865c7
Merge remote-tracking branch 'origin/develop' into script-feature
leotrj Mar 22, 2017
58894be
work on sensor and pixi
TrevorEdwards Mar 22, 2017
510ae8a
Bug Fixes
leotrj Mar 23, 2017
3c80f7c
display background image for line follower'
alan20854 Mar 23, 2017
eeb6812
made small changes to incorporate snesor
leotrj Mar 23, 2017
43439f8
Merge remote-tracking branch 'origin/sensor_base' into script-feature
leotrj Mar 23, 2017
5fe397c
enabled, tested sensor offset on both medial and lateral axes
yangdanny97 Mar 23, 2017
dac6f40
sensor cmopatibility added
leotrj Mar 24, 2017
167eb06
Merge remote-tracking branch 'origin/sensor_base' into script-feature
leotrj Mar 25, 2017
5cfa2fb
Added read(), GIPOSensor Compatibility, and etc
leotrj Mar 25, 2017
4468ef4
bug fix
leotrj Mar 25, 2017
8a985b8
Add line follower code
jimmychen623 Mar 25, 2017
1b1a6f1
Changed read and readall so that it returns value
leotrj Mar 25, 2017
280beb2
removed output.txt
leotrj Mar 25, 2017
2177154
do sensor
yangdanny97 Mar 25, 2017
a089d80
ok
yangdanny97 Mar 25, 2017
8c7a380
Merge remote-tracking branch 'origin/sensor_base' into script-feature
leotrj Mar 25, 2017
090f624
Small adjustment to work with multiple sensors
leotrj Mar 25, 2017
037c784
Added line following script and changed the sensor to be more inline …
leotrj Mar 25, 2017
582e50b
Added comments and removed extraneous code
leotrj Mar 27, 2017
917ae98
Deleted script, deleted uneccessary comments, fixed scriptheader clas…
leotrj Mar 29, 2017
8e62249
changed simbot name
leotrj Apr 13, 2017
aa6f063
Fixed bot name dropdown
leotrj Apr 14, 2017
c71fa07
Resolve pull 14 issues
jimmychen623 Apr 15, 2017
1e37b73
Merge remote-tracking branch 'origin/develop' into script-feature
jimmychen623 Apr 15, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions python-interface/src/received/line_follower.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from cup_minibot_prepend import CupMiniBot
from .sensor.Sensor import Sensor
bot = CupMiniBot()
left = Sensor(bot, 'left')
right = Sensor(bot, 'right')
center = Sensor(bot, 'center')

end = False
while(not end):

while(center.read()==1):
bot.move_foward(100)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this script doesn't compile- can you put the most recent working one up?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't worry about it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i did already i thinks?

while(center.read() != 1):
if(left.read() == 1):
bot.turn_clockwise(100)
else if(right.read() == 1):
bot.turn_counter_clockwise(100)
else:
end = True
break
24 changes: 24 additions & 0 deletions python-interface/src/received/line_follower_demo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#COPY AND PASTE THIS CODE INTO THE GUI TERMINAL

# bot.move_forward(70)
# s = GPIOSensor(bot, 'right', 1)
# s1 = GPIOSensor(bot, 'left', 2)
# s2 = GPIOSensor(bot, 'center', 3)
# state = 0
# while(True):
# data = s.readAll()
# j = json.loads(data)
# center = j['center']['data']
# right = j['right']['data']
# left = j['left']['data']
#
# if left != 1 and right != 1:
# bot.move_forward(70)
# else:
# if left and right:
# bot.move_forward(70)
# state = 1
# elif right:
# bot.turn_clockwise(70)
# elif left:
# bot.turn_counter_clockwise(70)
168 changes: 168 additions & 0 deletions script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import socket
import sys
import time
import json

HOST = "localhost"
PORT = 11111

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

class SimMiniBot:
"""
Abstract simulator class defining the base functions of the MiniBot. More customized MiniBots may
subclass this.
"""
def __init__(self):
server_address = (HOST, PORT)
sock.connect(server_address)

def move_forward(self, power):
"""
Moves the bot forward at a percentage of its full power

:param power The percentage of the bot's power to use from 0-100
:return True if the action is supported
"""
message = "FORWARD:" + str(power) + '\n'
sock.sendall(message)
return

def move_backward(self, power):
"""
Moves the bot backward at a percentage of its full power

:param power The percentage of the bot's power to use from 0-100
:return True if the action is supported
"""
message = "BACKWARD:" + str(power) + '\n'
sock.sendall(message)
return

def turn_clockwise(self, power):
"""
Moves the bot clockwise at a percentage of its full power

:param power The percentage of the bot's power to use from 0-100
:return True if the action is supported
"""
message = "RIGHT:" + str(power) + '\n'
sock.sendall(message)
return

def turn_counter_clockwise(self, power):
"""
Moves the bot counter-clockwise at a percentage of its full power

:param power The percentage of the bot's power to use from 0-100
:return True if the action is supported
"""
message = "LEFT:" + str(power) + '\n'
sock.sendall(message)
return

def set_wheel_power(self, front_left, front_right, back_left, back_right):
"""
Sets the power of the bot's wheels as a percentage from -100 to 100. If a wheel
specified does not exist, the power for that wheel is ignored.
:param front_left power to deliver to the front_left wheel
:param front_right power to deliver to the front_right wheel
:param back_left power to deliver to the back_left wheel
:param back_right power to deliver to the back_right wheel
:return True if the action is supported
"""
message = "WHEELS:" + str(front_left) + ',' + str(front_right) + ',' + str(back_left) + ',' \
+ str(back_right) + '\n';
sock.sendall(message)
return

def wait(self, t):
"""
Waits for a duration in seconds.
:param t The duration in seconds
"""
message = "WAIT:" + str(t) + '\n'
sock.sendall(message)
time.sleep(t)
return

def stop(self):
"""
Waits for a duration in seconds.
:param t The duration in seconds
"""
message = "STOP:0" + '\n'
sock.sendall(message)
return

def register_sensor(self, name):
"""
Registers a new sensor.
:param name The name of the sensor
"""
message = "REGISTER:" + name + '\n'
sock.sendall(message)
return

def kill(self):
"""
Kills TCP connection
"""
message = "KILL:-1" + '\n'
sock.sendall(message)
sock.close()
return


class Sensor:
def __init__(self, bot, name):
self.name = name
bot.register_sensor(name)

def read(self):
return "Invalid: Abstract Sensor Class Reading"


class GPIOSensor(Sensor):
def __init__(self, bot, name, pin_number):
Sensor.__init__(self, bot, name)
self.pin_number = pin_number

def readAll(self):
"""
Get All Sensor Data
"""
message = "GET:ALL" + '\n'
sock.sendall(message)
result = sock.recv(1024)
return result

def read(self):
"""
Get Sensor Data
"""
message = "GET:" + self.name + '\n'
sock.sendall(message)
result = sock.recv(1024)
return result

bot = SimMiniBot()
bot.move_forward(70)
s = GPIOSensor(bot, 'bot1', 1)
state = 0
while(True):
data = s.readAll()
j = json.loads(data)
center = j['center']['data']
right = j['right']['data']
left = j['left']['data']

if left and right:
bot.move_forward(70)
elif right:
bot.turn_clockwise(70)
elif left:
bot.turn_counter_clockwise(70)
else:
if state == 0:
bot.move_forward(70)
19 changes: 16 additions & 3 deletions src/main/java/minibot/BaseHTTPInterface.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import simulator.physics.PhysicalObject;
import simulator.simbot.ColorIntensitySensor;
import simulator.simbot.SimBotConnection;
import simulator.simbot.SimBotSensorCenter;
import spark.route.RouteOverview;

import java.util.ArrayList;
Expand Down Expand Up @@ -88,13 +90,19 @@ public static void main(String[] args) {
}
else {
SimBotConnection sbc = new SimBotConnection();
newBot = new SimBot(sbc, name);

PhysicalObject po = new PhysicalObject("TESTBOT", 50, simvs.getWorld(), 0.4f, 0.0f, 1f, 1f, true);
PhysicalObject po = new PhysicalObject("simbot", 50, simvs.getWorld(), 0.0f, 0.0f, 1f, 3.6f, true);
SimBot simbot;
simbot = new SimBot(sbc, name, po);
newBot = simbot;

ArrayList<PhysicalObject> pObjs = new ArrayList<>();
pObjs.add(po);
simvs.processPhysicalObjects(pObjs);

// Color sensor TODO put somewhere nice
ColorIntensitySensor colorSensorL = new ColorIntensitySensor((SimBotSensorCenter) simbot.getSensorCenter(),"right",simbot, 5);
ColorIntensitySensor colorSensorR = new ColorIntensitySensor((SimBotSensorCenter) simbot.getSensorCenter(),"left",simbot, -5);
ColorIntensitySensor colorSensorM = new ColorIntensitySensor((SimBotSensorCenter) simbot.getSensorCenter(),"center",simbot, 0);
}

return BaseStation.getInstance().getBotManager().addBot(newBot);
Expand Down Expand Up @@ -143,6 +151,11 @@ public static void main(String[] args) {
String name = commandInfo.get("name").getAsString();
String script = commandInfo.get("script").getAsString();

((SimBot)BaseStation.getInstance()
.getBotManager()
.getBotByName(name)
.orElseThrow(NoSuchElementException::new)).resetServer();

return BaseStation.getInstance()
.getBotManager()
.getBotByName(name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.jbox2d.dynamics.World;

Expand All @@ -20,7 +21,7 @@ public class SimulatorVisionSystem extends VisionSystem {
* @param o A coordinate specifying the origin of the VisionSystem
*/
private static SimulatorVisionSystem instance;
private volatile HashSet<VisionObject> set;
private volatile Set<VisionObject> set;
private HashSet<PhysicalObject> po_set;
private World world;
private long before;
Expand All @@ -29,7 +30,7 @@ public class SimulatorVisionSystem extends VisionSystem {

public SimulatorVisionSystem() {
super(new VisionCoordinate(0, 0, 0));
set = new HashSet<>();
set = ConcurrentHashMap.newKeySet();
world = new World(new Vec2(0f, 0f));
po_set = new HashSet<>();
before = System.nanoTime();
Expand Down Expand Up @@ -57,7 +58,7 @@ public Set<VisionObject> getAllObjects() {
* @param pObjs The data sent from simulator
*/
public void processPhysicalObjects(ArrayList<PhysicalObject> pObjs) {
HashSet<VisionObject> newSet = new HashSet<>();
Set<VisionObject> newSet = ConcurrentHashMap.newKeySet();
for(PhysicalObject obj: pObjs) {
VisionCoordinate vc = new VisionCoordinate(obj.getX(),obj.getY(), 0.0);
VisionObject vo = new VisionObject(this,obj.getID(),vc);
Expand Down
88 changes: 88 additions & 0 deletions src/main/java/simulator/simbot/ColorIntensitySensor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package simulator.simbot;

import basestation.BaseStation;
import basestation.vision.VisionCoordinate;
import basestation.vision.VisionObject;
import com.google.gson.JsonObject;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;

/**
* A sensor that measures color intensity based on an image provided to the simulator.
*/
public class ColorIntensitySensor extends Sensor {

transient BufferedImage img;
private transient SimBot parent;
private double lateralOffset;

public ColorIntensitySensor(SimBotSensorCenter myCenter, String name, SimBot parent, double lateralOffset) {
super(myCenter, name);
this.parent = parent;
try {
img = ImageIO.read(new File("./src/main/resources/public/img/line.png"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to make this image configurable / uploadable. Can you make a GitHub issue referencing this pull request?

} catch (IOException e) {
e.printStackTrace();
}
this.lateralOffset = lateralOffset;
}

public JsonObject read() {
// Get the x,y coordinates of the bot.
// TODO: Make it so we can do this line, not the one below. VisionCoordinate parentCoordinate = BaseStation.getInstance().getVisionManager().getBotCoordinate(parent);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add this feature before the code is merged? (resolve the TODO)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to assign that to a platform member due b4 spring break

List<VisionObject> allLocs = BaseStation.getInstance().getVisionManager().getAllLocationData();
JsonObject jo = new JsonObject();

if (allLocs.size() == 0) {
jo.addProperty("data",-1);
return jo;
}

VisionCoordinate parentCoordinate = allLocs.get(0).coord;

if (parentCoordinate == null) {
jo.addProperty("data",-1);
return jo;
}


int[] transformed = transformToPixels(parentCoordinate, this.lateralOffset);

// Get pixel values
if(img==null) {
System.err.println("null image");
jo.addProperty("data", -1);
return jo;
}
int rgb = img.getRGB(transformed[0], transformed[1]);
if (rgb <= -16777216) {
rgb=1;
} else {
rgb=0;
}
jo.addProperty("data",rgb);


return jo;
}

private int[] transformToPixels(VisionCoordinate vc, double lateralOffset) {
double X_SCALE = 100;
double Y_SCALE = 100;
double medial_offset = 9.5; //offset along the medial axis of the robot, positive values indicate a "forwards" offset. 62.5 corresponds with offsetting it to the front of the bot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be nice if we could say what the units of this are.

double lateral_offset = lateralOffset; //offset along lateral axis of robot, positive values indicate a "leftwards" offset, 0 indicates that there is no left/right offset
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useless reassignment (also the previous one), please refactor to not do that

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yangdanny97 I think this was your section

int[] ret = new int[2];

double angle = vc.getThetaOrZero();
double angle_offset = Math.atan(lateral_offset/medial_offset)+angle; //intermediate step for calculating coordinates
double total_offset = Math.sqrt(medial_offset*medial_offset+lateral_offset*lateral_offset); //intermediate step for calculating coordinates

ret[0] = (int) Math.floor(vc.x * X_SCALE + total_offset*Math.cos(angle_offset));
ret[1] = (int) Math.floor(vc.y * Y_SCALE + total_offset*Math.sin(angle_offset));
return ret;
}
}
Loading