master
xyz 5 years ago
commit 77c9e6d63d

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="lib" path="lib/commons-codec/commons-codec-1.3.jar"/>
<classpathentry kind="lib" path="lib/freemarker.jar"/>
<classpathentry kind="lib" path="lib/jrosbridge/javax.json-1.0.4.jar"/>
<classpathentry kind="lib" path="lib/jrosbridge/javax.websocket-api-1.0-rc4.jar"/>
<classpathentry kind="lib" path="lib/jrosbridge/javax.websocket-api-1.0.jar"/>
<classpathentry kind="lib" path="lib/jrosbridge/tyrus-standalone-client-1.9.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="lib/substance5.2.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

@ -0,0 +1,5 @@
/bin/*
!/bin/icon1/*
!/bin/Icon/*
/null
/src/Shells/build

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>AutoRobotV1</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

@ -0,0 +1,7 @@
# AutoRobot-v1
两台电脑利用Ros通信(从机订阅主机的topic信息,从而观察主机工作状态):
https://blog.csdn.net/qq_42037180/article/details/81144561
ROS多个master消息互通:
https://www.cnblogs.com/shhu1993/p/6021396.html

@ -0,0 +1,5 @@
#Update SSHPath name
#Wed Feb 10 15:04:33 CST 2021
WorkPath=/home/xyz/workspace/ars_ws
RosPath=/opt/ros/melodic
SSHPath=huawei@202.197.85.29

Binary file not shown.

@ -0,0 +1,130 @@
#!/usr/bin/env python2
# coding:utf-8
import rospy
from std_msgs.msg import String
from std_msgs.msg import Float32MultiArray
from std_msgs.msg import MultiArrayLayout
import sys
from python import sim
from python.sim import *
from policy.orca import ORCA
import numpy as np
import time
# TODO:
from utils.human import Human
from utils.robot import Robot
import logging
import argparse
import configparser
from numpy.linalg import norm
actCmd = list()
class Interpreter():
def __init__(self, config, robot):
self.robot = robot
self.config = config
# self.clientID = clientID
sub = rospy.Subscriber('chatter', Float32MultiArray, self.callback)
self.pub = rospy.Publisher('act_cmd', Float32MultiArray, queue_size=2)
# self.policy = ORCA()
# TODO: initialize RVO2-Vrep sim
self.time_step = 0.25
# set Robot
self.circle_radius = config.getfloat('sim', 'circle_radius')
self.discomfort_dist = config.getfloat('reward', 'discomfort_dist')
self.robot.set(0, -self.circle_radius, 0, self.circle_radius, 0, 0, np.pi / 2)
np.random.seed(1)
self.generate_random_human_position(human_num=5)
for agent in [self.robot] + self.humans:
agent.time_step = self.time_step
agent.policy.time_step = self.time_step
# 把后边可能用到的 sub, pub 在初始化函数中定义好
def callback(self, data):
if (len(data.data)!=0):
rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)
envState = list(data.data)
# TODO: procedure to transfer envState to actCmd, just the decision-making procedure
# prepare state info
retFloats = envState
for index, human in enumerate(self.humans):
human.set_position([retFloats[4 * (index + 1) + 0], retFloats[4 * (index + 1) + 1]])
human.set_velocity([retFloats[4 * (index + 1) + 2], retFloats[4 * (index + 1) + 3]])
pass
self.robot.set_position([retFloats[0], retFloats[1]])
self.robot.set_velocity([retFloats[2], retFloats[3]])
ob = [human.get_observable_state() for human in self.humans]
action = self.robot.act(ob)
# get act for each agent, generate actCmd
human_actions = []
for human in self.humans:
# observation for humans is always coordinates
ob = [other_human.get_observable_state() for other_human in self.humans if other_human != human]
human_actions.append(human.act(ob))
theta = np.arctan2(action.vy, action.vx)
velocity = np.hypot(action.vx, action.vy)
all_actions = [velocity, theta]
for human_action in human_actions:
theta = np.arctan2(human_action.vy, human_action.vx)
velocity = np.hypot(human_action.vx, human_action.vy)
all_actions.extend([velocity, theta])
pass
actCmd = all_actions #[1.0 for i in range(12)]
data = Float32MultiArray()
# retFloats = [round(i,4) for i in retFloats]
data.data = actCmd
# data.layout = MultiArrayLayout()
self.pub.publish(data)
def generate_random_human_position(self, human_num):
self.humans = []
for i in range(human_num):
self.humans.append(self.generate_circle_crossing_human())
def generate_circle_crossing_human(self):
human = Human(self.config, 'humans')
while True:
angle = np.random.random() * np.pi * 2
# add some noise to simulate all the possible cases robot could meet with human
px_noise = (np.random.random() - 0.5) * human.v_pref
py_noise = (np.random.random() - 0.5) * human.v_pref
px = self.circle_radius * np.cos(angle) + px_noise
py = self.circle_radius * np.sin(angle) + py_noise
collide = False
for agent in [self.robot] + self.humans:
min_dist = human.radius + agent.radius + self.discomfort_dist
if norm((px - agent.px, py - agent.py)) < min_dist or \
norm((px - agent.gx, py - agent.gy)) < min_dist:
collide = True
break
if not collide:
break
human.set(px, py, -px, -py, 0, 0, 0)
return human
if __name__ == '__main__':
print('Vrep Sim Program started 2')
# configure environment
parser = argparse.ArgumentParser('Parse configuration file')
parser.add_argument('--env_config', type=str, default='env.config')
args = parser.parse_args()
env_config = configparser.RawConfigParser()
env_config.read(args.env_config)
robot = Robot(env_config, 'robot')
rospy.init_node('interpreter')
try:
Interpreter(env_config, robot)
except rospy.ROSInterruptException:
pass
# rate = rospy.Rate(250)
# while not rospy.is_shutdown():
# rate.sleep()
rospy.spin()

@ -0,0 +1,37 @@
[env]
time_limit = 45
time_step = 0.3
val_size = 10
test_size = 100
randomize_attributes = false
[reward]
success_reward = 1
collision_penalty = -0.25
discomfort_dist = 0.1
discomfort_penalty_factor = 0.5
[sim]
train_val_sim = circle_crossing
test_sim = circle_crossing
square_width = 5
circle_radius = 2
human_num = 5
[humans]
visible = true
policy = orca
radius = 0.15
v_pref = 0.5
sensor = coordinates
[robot]
visible = false
policy = orca
radius = 0.15
v_pref = 0.5
sensor = coordinates

@ -0,0 +1,53 @@
#!/usr/bin/env python2
import rospy
from std_msgs.msg import String
from std_msgs.msg import Float32MultiArray
from std_msgs.msg import MultiArrayLayout
import sys
sys.path.append ('./python')
import sim
from sim import *
actCmd = list()
def callback(data):
if (len(data.data)!=0):
rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)
actCmd = list(data.data)
# print(actCmd)
res, retInts, retFloats, retStrings, retBuffer = sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'setRobotVel', [],actCmd, [], '',sim.simx_opmode_blocking)
def listener():
sub = rospy.Subscriber('act_cmd', Float32MultiArray, callback)
rospy.init_node('listener', anonymous=False)
rate = rospy.Rate(250)
while not rospy.is_shutdown():
rate.sleep()
if __name__ == '__main__':
print('Vrep Sim Program started 2')
sim.simxFinish(-1) # just in case, close all opened connections
clientID = sim.simxStart('127.0.0.1', 19997, True, True, 5000, 5) # Connect to CoppeliaSim
if clientID != -1:
print('Connected to remote API server 2')
# Now try to retrieve data in a blocking fashion (i.e. a service call):
res, objs = sim.simxGetObjects(clientID, sim.sim_handle_all, sim.simx_opmode_blocking)
if res == sim.simx_return_ok:
print('Number of objects in the scene 2: ', len(objs))
else:
print('Remote API function call returned with error code: ', res)
# time.sleep(2)
else:
print('Failed connecting to remote API server')
listener()
#
# rostopic pub -1 /act_cmd std_msgs/Float32MultiArray -- "{\"data\":[0.30720001459121704,0.00019999999494757503],\"layout\":{\"dim\":[],\"data_offset\":0}}"
# "{\"data\":[0.30720001459121704,0.00019999999494757503],\"layout\":{\"dim\":[],\"data_offset\":0}}"

@ -0,0 +1,133 @@
import numpy as np
import rvo2
from policy import Policy
import sys
from utils.action import ActionXY
class ORCA(Policy):
def __init__(self):
"""
timeStep The time step of the simulation.
Must be positive.
neighborDist The default maximum distance (center point
to center point) to other agents a new agent
takes into account in the navigation. The
larger this number, the longer the running
time of the simulation. If the number is too
low, the simulation will not be safe. Must be
non-negative.
maxNeighbors The default maximum number of other agents a
new agent takes into account in the
navigation. The larger this number, the
longer the running time of the simulation.
If the number is too low, the simulation
will not be safe.
timeHorizon The default minimal amount of time for which
a new agent's velocities that are computed
by the simulation are safe with respect to
other agents. The larger this number, the
sooner an agent will respond to the presence
of other agents, but the less freedom the
agent has in choosing its velocities.
Must be positive.
timeHorizonObst The default minimal amount of time for which
a new agent's velocities that are computed
by the simulation are safe with respect to
obstacles. The larger this number, the
sooner an agent will respond to the presence
of obstacles, but the less freedom the agent
has in choosing its velocities.
Must be positive.
radius The default radius of a new agent.
Must be non-negative.
maxSpeed The default maximum speed of a new agent.
Must be non-negative.
velocity The default initial two-dimensional linear
velocity of a new agent (optional).
ORCA first uses neighborDist and maxNeighbors to find neighbors that need to be taken into account.
Here set them to be large enough so that all agents will be considered as neighbors.
Time_horizon should be set that at least it's safe for one time step
In this work, obstacles are not considered. So the value of time_horizon_obst doesn't matter.
"""
super(ORCA, self).__init__()
self.name = 'ORCA'
self.trainable = False
self.multiagent_training = None
self.kinematics = 'holonomic'
self.safety_space = 0
self.neighbor_dist = 10
self.max_neighbors = 10
self.time_horizon = 5
self.time_horizon_obst = 5
self.radius = 0.15
self.max_speed = 0.5
self.sim = None
def configure(self, config):
# self.time_step = config.getfloat('orca', 'time_step')
# self.neighbor_dist = config.getfloat('orca', 'neighbor_dist')
# self.max_neighbors = config.getint('orca', 'max_neighbors')
# self.time_horizon = config.getfloat('orca', 'time_horizon')
# self.time_horizon_obst = config.getfloat('orca', 'time_horizon_obst')
# self.radius = config.getfloat('orca', 'radius')
# self.max_speed = config.getfloat('orca', 'max_speed')
return
def set_phase(self, phase):
return
def predict(self, state):
"""
Create a rvo2 simulation at each time step and run one step
Python-RVO2 API: https://github.com/sybrenstuvel/Python-RVO2/blob/master/src/rvo2.pyx
How simulation is done in RVO2: https://github.com/sybrenstuvel/Python-RVO2/blob/master/src/Agent.cpp
Agent doesn't stop moving after it reaches the goal, because once it stops moving, the reciprocal rule is broken
:param state:
:return:
"""
self_state = state.self_state
params = self.neighbor_dist, self.max_neighbors, self.time_horizon, self.time_horizon_obst
if self.sim is not None and self.sim.getNumAgents() != len(state.human_states) + 1:
del self.sim
self.sim = None
if self.sim is None:
self.sim = rvo2.PyRVOSimulator(self.time_step, self.neighbor_dist, self.max_neighbors, self.time_horizon, self.time_horizon_obst, self.radius, self.max_speed)
self.sim.addAgent(self_state.position, self.neighbor_dist, self.max_neighbors, self.time_horizon, self.time_horizon_obst, self_state.radius + 0.01 + self.safety_space,
self_state.v_pref, self_state.velocity)
for human_state in state.human_states:
self.sim.addAgent(human_state.position, self.neighbor_dist, self.max_neighbors, self.time_horizon, self.time_horizon_obst, human_state.radius + 0.01 + self.safety_space,
self.max_speed, human_state.velocity)
else:
self.sim.setAgentPosition(0, self_state.position)
self.sim.setAgentVelocity(0, self_state.velocity)
for i, human_state in enumerate(state.human_states):
self.sim.setAgentPosition(i + 1, human_state.position)
self.sim.setAgentVelocity(i + 1, human_state.velocity)
# Set the preferred velocity to be a vector of unit magnitude (speed) in the direction of the goal.
velocity = np.array((self_state.gx - self_state.px, self_state.gy - self_state.py))
speed = np.linalg.norm(velocity)
pref_vel = velocity / speed if speed > 1 else velocity
# Perturb a little to avoid deadlocks due to perfect symmetry.
# perturb_angle = np.random.random() * 2 * np.pi
# perturb_dist = np.random.random() * 0.01
# perturb_vel = np.array((np.cos(perturb_angle), np.sin(perturb_angle))) * perturb_dist
# pref_vel += perturb_vel
self.sim.setAgentPrefVelocity(0, tuple(pref_vel))
for i, human_state in enumerate(state.human_states):
# unknown goal position of other humans
self.sim.setAgentPrefVelocity(i + 1, (0, 0))
self.sim.doStep()
action = ActionXY(*self.sim.getAgentVelocity(0))
self.last_state = state
return action

@ -0,0 +1,53 @@
import abc
import numpy as np
class Policy(object):
def __init__(self):
"""
Base class for all policies, has an abstract method predict().
"""
self.trainable = False
self.phase = None
self.model = None
self.modeldl = None
self.device = None
self.last_state = None
self.time_step = None
# if agent is assumed to know the dynamics of real world
self.env = None
@abc.abstractmethod
def configure(self, config):
return
def set_phase(self, phase):
self.phase = phase
def set_device(self, device):
self.device = device
def set_env(self, env):
self.env = env
def get_model(self):
return self.model
def get_modeldl(self):
return self.modeldl
@abc.abstractmethod
def predict(self, state):
"""
Policy takes state as input and output an action
"""
return
@staticmethod
def reach_destination(state):
self_state = state.self_state
if np.linalg.norm((self_state.py - self_state.gy, self_state.px - self_state.gx)) < self_state.radius:
return True
else:
return False

@ -0,0 +1,9 @@
from orca import ORCA
def none_policy():
return None
policy_factory = dict()
policy_factory['orca'] = ORCA
policy_factory['none'] = none_policy

@ -0,0 +1,59 @@
# This example illustrates how to execute complex commands from
# a remote API client. You can also use a similar construct for
# commands that are not directly supported by the remote API.
#
# Load the demo scene 'remoteApiCommandServerExample.ttt' in CoppeliaSim, then
# start the simulation and run this program.
#
# IMPORTANT: for each successful call to simxStart, there
# should be a corresponding call to simxFinish at the end!
try:
import sim
except:
print ('--------------------------------------------------------------')
print ('"sim.py" could not be imported. This means very probably that')
print ('either "sim.py" or the remoteApi library could not be found.')
print ('Make sure both are in the same folder as this file,')
print ('or appropriately adjust the file "sim.py"')
print ('--------------------------------------------------------------')
print ('')
import sys
import ctypes
print ('Program started')
sim.simxFinish(-1) # just in case, close all opened connections
clientID=sim.simxStart('127.0.0.1',19999,True,True,5000,5) # Connect to CoppeliaSim
if clientID!=-1:
print ('Connected to remote API server')
# 1. First send a command to display a specific message in a dialog box:
emptyBuff = bytearray()
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'displayText_function',[],[],['Hello world!'],emptyBuff,sim.simx_opmode_blocking)
if res==sim.simx_return_ok:
print ('Return string: ',retStrings[0]) # display the reply from CoppeliaSim (in this case, just a string)
else:
print ('Remote function call failed')
# 2. Now create a dummy object at coordinate 0.1,0.2,0.3 with name 'MyDummyName':
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'createDummy_function',[],[0.1,0.2,0.3],['MyDummyName'],emptyBuff,sim.simx_opmode_blocking)
if res==sim.simx_return_ok:
print ('Dummy handle: ',retInts[0]) # display the reply from CoppeliaSim (in this case, the handle of the created dummy)
else:
print ('Remote function call failed')
# 3. Now send a code string to execute some random functions:
code="local octreeHandle=simCreateOctree(0.5,0,1)\n" \
"simInsertVoxelsIntoOctree(octreeHandle,0,{0.1,0.1,0.1},{255,0,255})\n" \
"return 'done'"
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,"remoteApiCommandServer",sim.sim_scripttype_childscript,'executeCode_function',[],[],[code],emptyBuff,sim.simx_opmode_blocking)
if res==sim.simx_return_ok:
print ('Code execution returned: ',retStrings[0])
else:
print ('Remote function call failed')
# Now close the connection to CoppeliaSim:
sim.simxFinish(clientID)
else:
print ('Failed connecting to remote API server')
print ('Program ended')

@ -0,0 +1,229 @@
"""Creates an image from a numpy array of floating point depth data.
For details about the encoding see:
https://sites.google.com/site/brainrobotdata/home/depth-image-encoding
Examples:
depth_array is a 2D numpy array of floating point depth data in meters.
depth_rgb = FloatArrayToRgbImage(depth_array)
depth_rgb is a PIL Image object containing the same data as 24-bit
integers encoded in the RGB bytes.
depth_rgb.save('image_file.png') - to save to a file.
depth_array2 = ImageToFloatArray(depth_rgb)
depth_array2 is a 2D numpy array containing the same data as
depth_array up to the precision of the RGB image (1/256 mm).
depth_gray = FloatArrayToGrayImage(depth_array)
depth_gray is a PIL Image object containing the same data rounded to
8-bit integers.
depth_gray.save('image_file.jpg', quality=95) - to save to a file.
depth_array3 = ImageToFloatArray(depth_gray)
depth_array3 is a 2D numpy array containing the same data as
depth_array up to the precision of the grayscale image (1 cm).
The image conversions first scale and round the values and then pack
them into the desired type in a numpy array before converting the
array to a PIL Image object. The Image can be saved in any format.
We are using PNG for RGB and high quality JPEG for grayscale images.
You can use different numeric types (e.g. np.uint16, np.int32), but
not all combinations of numeric type and image format are supported by
PIL or standard image viewers.
"""
import numpy as np
from PIL import Image
from skimage import img_as_ubyte
from skimage.color import grey2rgb
def ClipFloatValues(float_array, min_value, max_value):
"""Clips values to the range [min_value, max_value].
First checks if any values are out of range and prints a message.
Then clips all values to the given range.
Args:
float_array: 2D array of floating point values to be clipped.
min_value: Minimum value of clip range.
max_value: Maximum value of clip range.
Returns:
The clipped array.
"""
if float_array.min() < min_value or float_array.max() > max_value:
print('Image has out-of-range values [%f,%f] not in [%d,%d]',
float_array.min(), float_array.max(), min_value, max_value)
float_array = np.clip(float_array, min_value, max_value)
return float_array
DEFAULT_RGB_SCALE_FACTOR = 256000.0
def FloatArrayToRgbImage(float_array,
scale_factor=DEFAULT_RGB_SCALE_FACTOR,
drop_blue=False):
"""Convert a floating point array of values to an RGB image.
Convert floating point values to a fixed point representation where
the RGB bytes represent a 24-bit integer.
R is the high order byte.
B is the low order byte.
The precision of the depth image is 1/256 mm.
Floating point values are scaled so that the integer values cover
the representable range of depths.
This image representation should only use lossless compression.
Args:
float_array: Input array of floating point depth values in meters.
scale_factor: Scale value applied to all float values.
drop_blue: Zero out the blue channel to improve compression, results in 1mm
precision depth values.
Returns:
24-bit RGB PIL Image object representing depth values.
"""
float_array = np.squeeze(float_array)
# Scale the floating point array.
scaled_array = np.floor(float_array * scale_factor + 0.5)
# Convert the array to integer type and clip to representable range.
min_inttype = 0
max_inttype = 2**24 - 1
scaled_array = ClipFloatValues(scaled_array, min_inttype, max_inttype)
int_array = scaled_array.astype(np.uint32)
# Calculate:
# r = (f / 256) / 256 high byte
# g = (f / 256) % 256 middle byte
# b = f % 256 low byte
rg = np.divide(int_array, 256)
r = np.divide(rg, 256)
g = np.mod(rg, 256)
image_shape = int_array.shape
rgb_array = np.zeros((image_shape[0], image_shape[1], 3), dtype=np.uint8)
rgb_array[..., 0] = r
rgb_array[..., 1] = g
if not drop_blue:
# Calculate the blue channel and add it to the array.
b = np.mod(int_array, 256)
rgb_array[..., 2] = b
image_mode = 'RGB'
image = Image.fromarray(rgb_array, mode=image_mode)
return image
DEFAULT_GRAY_SCALE_FACTOR = {np.uint8: 100.0,
np.uint16: 1000.0,
np.int32: DEFAULT_RGB_SCALE_FACTOR}
def FloatArrayToGrayImage(float_array, scale_factor=None, image_dtype=np.uint8):
"""Convert a floating point array of values to an RGB image.
Convert floating point values to a fixed point representation with
the given bit depth.
The precision of the depth image with default scale_factor is:
uint8: 1cm, with a range of [0, 2.55m]
uint16: 1mm, with a range of [0, 65.5m]
int32: 1/256mm, with a range of [0, 8388m]
Right now, PIL turns uint16 images into a very strange format and
does not decode int32 images properly. Only uint8 works correctly.
Args:
float_array: Input array of floating point depth values in meters.
scale_factor: Scale value applied to all float values.
image_dtype: Image datatype, which controls the bit depth of the grayscale
image.
Returns:
Grayscale PIL Image object representing depth values.
"""
# Ensure that we have a valid numeric type for the image.
if image_dtype == np.uint16:
image_mode = 'I;16'
elif image_dtype == np.int32:
image_mode = 'I'
else:
image_dtype = np.uint8
image_mode = 'L'
if scale_factor is None:
scale_factor = DEFAULT_GRAY_SCALE_FACTOR[image_dtype]
# Scale the floating point array.
scaled_array = np.floor(float_array * scale_factor + 0.5)
# Convert the array to integer type and clip to representable range.
min_dtype = np.iinfo(image_dtype).min
max_dtype = np.iinfo(image_dtype).max
scaled_array = ClipFloatValues(scaled_array, min_dtype, max_dtype)
image_array = scaled_array.astype(image_dtype)
image = Image.fromarray(image_array, mode=image_mode)
return image
def ImageToFloatArray(image, scale_factor=None):
"""Recovers the depth values from an image.
Reverses the depth to image conversion performed by FloatArrayToRgbImage or
FloatArrayToGrayImage.
The image is treated as an array of fixed point depth values. Each
value is converted to float and scaled by the inverse of the factor
that was used to generate the Image object from depth values. If
scale_factor is specified, it should be the same value that was
specified in the original conversion.
The result of this function should be equal to the original input
within the precision of the conversion.
For details see https://sites.google.com/site/brainrobotdata/home/depth-image-encoding.
Args:
image: Depth image output of FloatArrayTo[Format]Image.
scale_factor: Fixed point scale factor.
Returns:
A 2D floating point numpy array representing a depth image.
"""
image_array = np.array(image)
image_dtype = image_array.dtype
image_shape = image_array.shape
channels = image_shape[2] if len(image_shape) > 2 else 1
assert 2 <= len(image_shape) <= 3
if channels == 3:
# RGB image needs to be converted to 24 bit integer.
float_array = np.sum(image_array * [65536, 256, 1], axis=2)
if scale_factor is None:
scale_factor = DEFAULT_RGB_SCALE_FACTOR
else:
if scale_factor is None:
scale_factor = DEFAULT_GRAY_SCALE_FACTOR[image_dtype.type]
float_array = image_array.astype(np.float32)
scaled_array = float_array / scale_factor
return scaled_array
def FloatArrayToRawRGB(im, min_value=0.0, max_value=1.0):
"""Convert a grayscale image to rgb, no encoding.
For proper display try matplotlib's rendering/conversion instead of this version.
Please be aware that this does not incorporate a proper color transform.
http://pillow.readthedocs.io/en/3.4.x/reference/Image.html#PIL.Image.Image.convert
https://en.wikipedia.org/wiki/Rec._601
"""
im = img_as_ubyte(im)
if im.shape[-1] == 1:
im = grey2rgb(im)
return im

@ -0,0 +1,160 @@
# This example illustrates how to use the path/motion
# planning functionality from a remote API client.
#
# Load the demo scene 'motionPlanningServerDemo.ttt' in CoppeliaSim
# then run this program.
#
# IMPORTANT: for each successful call to simxStart, there
# should be a corresponding call to simxFinish at the end!
import sim
print ('Program started')
sim.simxFinish(-1) # just in case, close all opened connections
clientID=sim.simxStart('127.0.0.1',19997,True,True,-500000,5) # Connect to CoppeliaSim, set a very large time-out for blocking commands
if clientID!=-1:
print ('Connected to remote API server')
emptyBuff = bytearray()
# Start the simulation:
sim.simxStartSimulation(clientID,sim.simx_opmode_oneshot_wait)
# Load a robot instance: res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'loadRobot',[],[0,0,0,0],['d:/coppeliaRobotics/qrelease/release/test.ttm'],emptyBuff,sim.simx_opmode_oneshot_wait)
# robotHandle=retInts[0]
# Retrieve some handles:
res,robotHandle=sim.simxGetObjectHandle(clientID,'IRB4600#',sim.simx_opmode_oneshot_wait)
res,target1=sim.simxGetObjectHandle(clientID,'testPose1#',sim.simx_opmode_oneshot_wait)
res,target2=sim.simxGetObjectHandle(clientID,'testPose2#',sim.simx_opmode_oneshot_wait)
res,target3=sim.simxGetObjectHandle(clientID,'testPose3#',sim.simx_opmode_oneshot_wait)
res,target4=sim.simxGetObjectHandle(clientID,'testPose4#',sim.simx_opmode_oneshot_wait)
# Retrieve the poses (i.e. transformation matrices, 12 values, last row is implicit) of some dummies in the scene
res,retInts,target1Pose,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'getObjectPose',[target1],[],[],emptyBuff,sim.simx_opmode_oneshot_wait)
res,retInts,target2Pose,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'getObjectPose',[target2],[],[],emptyBuff,sim.simx_opmode_oneshot_wait)
res,retInts,target3Pose,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'getObjectPose',[target3],[],[],emptyBuff,sim.simx_opmode_oneshot_wait)
res,retInts,target4Pose,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'getObjectPose',[target4],[],[],emptyBuff,sim.simx_opmode_oneshot_wait)
# Get the robot initial state:
res,retInts,robotInitialState,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'getRobotState',[robotHandle],[],[],emptyBuff,sim.simx_opmode_oneshot_wait)
# Some parameters:
approachVector=[0,0,1] # often a linear approach is required. This should also be part of the calculations when selecting an appropriate state for a given pose
maxConfigsForDesiredPose=10 # we will try to find 10 different states corresponding to the goal pose and order them according to distance from initial state
maxTrialsForConfigSearch=300 # a parameter needed for finding appropriate goal states
searchCount=2 # how many times OMPL will run for a given task
minConfigsForPathPlanningPath=400 # interpolation states for the OMPL path
minConfigsForIkPath=100 # interpolation states for the linear approach path
collisionChecking=1 # whether collision checking is on or off
# Display a message:
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'displayMessage',[],[],['Computing and executing several path planning tasks for a given goal pose.&&nSeveral goal states corresponding to the goal pose are tested.&&nFeasability of a linear approach is also tested. Collision detection is on.'],emptyBuff,sim.simx_opmode_oneshot_wait)
# Do the path planning here (between a start state and a goal pose, including a linear approach phase):
inInts=[robotHandle,collisionChecking,minConfigsForIkPath,minConfigsForPathPlanningPath,maxConfigsForDesiredPose,maxTrialsForConfigSearch,searchCount]
inFloats=robotInitialState+target1Pose+approachVector
res,retInts,path,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'findPath_goalIsPose',inInts,inFloats,[],emptyBuff,sim.simx_opmode_oneshot_wait)
if (res==0) and len(path)>0:
# The path could be in 2 parts: a path planning path, and a linear approach path:
part1StateCnt=retInts[0]
part2StateCnt=retInts[1]
path1=path[:part1StateCnt*6]
# Visualize the first path:
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'visualizePath',[robotHandle,255,0,255],path1,[],emptyBuff,sim.simx_opmode_oneshot_wait)
line1Handle=retInts[0]
# Make the robot follow the path:
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'runThroughPath',[robotHandle],path1,[],emptyBuff,sim.simx_opmode_oneshot_wait)
# Wait until the end of the movement:
runningPath=True
while runningPath:
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'isRunningThroughPath',[robotHandle],[],[],emptyBuff,sim.simx_opmode_oneshot_wait)
runningPath=retInts[0]==1
path2=path[part1StateCnt*6:]
# Visualize the second path (the linear approach):
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'visualizePath',[robotHandle,0,255,0],path2,[],emptyBuff,sim.simx_opmode_oneshot_wait)
line2Handle=retInts[0]
# Make the robot follow the path:
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'runThroughPath',[robotHandle],path2,[],emptyBuff,sim.simx_opmode_oneshot_wait)
# Wait until the end of the movement:
runningPath=True
while runningPath:
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'isRunningThroughPath',[robotHandle],[],[],emptyBuff,sim.simx_opmode_oneshot_wait)
runningPath=retInts[0]==1
# Clear the paths visualizations:
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'removeLine',[line1Handle],[],[],emptyBuff,sim.simx_opmode_oneshot_wait)
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'removeLine',[line2Handle],[],[],emptyBuff,sim.simx_opmode_oneshot_wait)
# Get the robot current state:
res,retInts,robotCurrentConfig,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'getRobotState',[robotHandle],[],[],emptyBuff,sim.simx_opmode_oneshot_wait)
# Display a message:
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'displayMessage',[],[],['Computing and executing several path planning tasks for a given goal state. Collision detection is on.'],emptyBuff,sim.simx_opmode_oneshot_wait)
# Do the path planning here (between a start state and a goal state):
inInts=[robotHandle,collisionChecking,minConfigsForPathPlanningPath,searchCount]
inFloats=robotCurrentConfig+robotInitialState
res,retInts,path,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'findPath_goalIsState',inInts,inFloats,[],emptyBuff,sim.simx_opmode_oneshot_wait)
if (res==0) and len(path)>0:
# Visualize the path:
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'visualizePath',[robotHandle,255,0,255],path,[],emptyBuff,sim.simx_opmode_oneshot_wait)
lineHandle=retInts[0]
# Make the robot follow the path:
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'runThroughPath',[robotHandle],path,[],emptyBuff,sim.simx_opmode_oneshot_wait)
# Wait until the end of the movement:
runningPath=True
while runningPath:
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'isRunningThroughPath',[robotHandle],[],[],emptyBuff,sim.simx_opmode_oneshot_wait)
runningPath=retInts[0]==1
# Clear the path visualization:
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'removeLine',[lineHandle],[],[],emptyBuff,sim.simx_opmode_oneshot_wait)
# Collision checking off:
collisionChecking=0
# Display a message:
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'displayMessage',[],[],['Computing and executing several linear paths, going through several waypoints. Collision detection is OFF.'],emptyBuff,sim.simx_opmode_oneshot_wait)
# Find a linear path that runs through several poses:
inInts=[robotHandle,collisionChecking,minConfigsForIkPath]
inFloats=robotInitialState+target2Pose+target1Pose+target3Pose+target4Pose
res,retInts,path,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'findIkPath',inInts,inFloats,[],emptyBuff,sim.simx_opmode_oneshot_wait)
if (res==0) and len(path)>0:
# Visualize the path:
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'visualizePath',[robotHandle,0,255,255],path,[],emptyBuff,sim.simx_opmode_oneshot_wait)
line1Handle=retInts[0]
# Make the robot follow the path:
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'runThroughPath',[robotHandle],path,[],emptyBuff,sim.simx_opmode_oneshot_wait)
# Wait until the end of the movement:
runningPath=True
while runningPath:
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'isRunningThroughPath',[robotHandle],[],[],emptyBuff,sim.simx_opmode_oneshot_wait)
runningPath=retInts[0]==1
# Clear the path visualization:
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'removeLine',[line1Handle],[],[],emptyBuff,sim.simx_opmode_oneshot_wait)
# Stop simulation:
sim.simxStopSimulation(clientID,sim.simx_opmode_oneshot_wait)
# Now close the connection to CoppeliaSim:
sim.simxFinish(clientID)
else:
print ('Failed connecting to remote API server')
print ('Program ended')

@ -0,0 +1,83 @@
# MIT LICENSE
# https://github.com/bponsler/kinectToPly/blob/master/kinectToPly.py
import numpy as np
class Ply(object):
'''The Ply class provides the ability to write a point cloud represented
by two arrays: an array of points (num points, 3), and an array of colors
(num points, 3) to a PLY file.
'''
def __init__(self, points, colors):
'''
* points -- The matrix of points (num points, 3)
* colors -- The matrix of colors (num points, 3)
'''
self.__points = points
self.__colors = colors
def write(self, filename):
'''Write the point cloud data to a PLY file of the given name.
* filename -- The PLY file
'''
# Write the headers
lines = self.__getLinesForHeader()
fd = open(filename, "w")
for line in lines:
fd.write("%s\n" % line)
# Write the points
self.__writePoints(fd, self.__points, self.__colors)
fd.close()
def __getLinesForHeader(self):
'''Get the list of lines for the PLY header.'''
lines = [
"ply",
"format ascii 1.0",
"comment generated by: kinectToPly",
"element vertex %s" % len(self.__points),
"property float x",
"property float y",
"property float z",
"property uchar red",
"property uchar green",
"property uchar blue",
"end_header",
]
return lines
def __writePoints(self, fd, points, colors):
'''Write the point cloud points to a file.
* fd -- The file descriptor
* points -- The matrix of points (num points, 3)
* colors -- The matrix of colors (num points, 3)
'''
# Stack the two arrays together
stacked = np.column_stack((points, colors))
# Write the array to the file
np.savetxt(
fd,
stacked,
delimiter='\n',
fmt="%f %f %f %d %d %d")
def write_xyz_rgb_as_ply(point_cloud, rgb_image, path):
"""Write a point cloud with associated rgb image to a ply file
# Arguments
point_cloud: xyz point cloud in format [height, width, channels]
rgb_image: uint8 image in format [height, width, channels]
path: Where to save the file, ex: '/path/to/folder/file.ply'
"""
xyz = point_cloud.reshape([point_cloud.size/3, 3])
rgb = np.squeeze(rgb_image).reshape([point_cloud.size/3, 3])
ply = Ply(xyz, rgb)
ply.write(path)

@ -0,0 +1,6 @@
Make sure you have following files in your directory, in order to run the various examples:
1. sim.py
2. simConst.py
3. the appropriate remote API library: "remoteApi.dll" (Windows), "remoteApi.dylib" (Mac) or "remoteApi.so" (Linux)
4. simpleTest.py (or any other example file)

File diff suppressed because it is too large Load Diff

Binary file not shown.

@ -0,0 +1,783 @@
#constants
#Scene object types. Values are serialized
sim_object_shape_type =0
sim_object_joint_type =1
sim_object_graph_type =2
sim_object_camera_type =3
sim_object_dummy_type =4
sim_object_proximitysensor_type =5
sim_object_reserved1 =6
sim_object_reserved2 =7
sim_object_path_type =8
sim_object_visionsensor_type =9
sim_object_volume_type =10
sim_object_mill_type =11
sim_object_forcesensor_type =12
sim_object_light_type =13
sim_object_mirror_type =14
#General object types. Values are serialized
sim_appobj_object_type =109
sim_appobj_collision_type =110
sim_appobj_distance_type =111
sim_appobj_simulation_type =112
sim_appobj_ik_type =113
sim_appobj_constraintsolver_type=114
sim_appobj_collection_type =115
sim_appobj_ui_type =116
sim_appobj_script_type =117
sim_appobj_pathplanning_type =118
sim_appobj_RESERVED_type =119
sim_appobj_texture_type =120
# Ik calculation methods. Values are serialized
sim_ik_pseudo_inverse_method =0
sim_ik_damped_least_squares_method =1
sim_ik_jacobian_transpose_method =2
# Ik constraints. Values are serialized
sim_ik_x_constraint =1
sim_ik_y_constraint =2
sim_ik_z_constraint =4
sim_ik_alpha_beta_constraint=8
sim_ik_gamma_constraint =16
sim_ik_avoidance_constraint =64
# Ik calculation results
sim_ikresult_not_performed =0
sim_ikresult_success =1
sim_ikresult_fail =2
# Scene object sub-types. Values are serialized
# Light sub-types
sim_light_omnidirectional_subtype =1
sim_light_spot_subtype =2
sim_light_directional_subtype =3
# Joint sub-types
sim_joint_revolute_subtype =10
sim_joint_prismatic_subtype =11
sim_joint_spherical_subtype =12
# Shape sub-types
sim_shape_simpleshape_subtype =20
sim_shape_multishape_subtype =21
# Proximity sensor sub-types
sim_proximitysensor_pyramid_subtype =30
sim_proximitysensor_cylinder_subtype=31
sim_proximitysensor_disc_subtype =32
sim_proximitysensor_cone_subtype =33
sim_proximitysensor_ray_subtype =34
# Mill sub-types
sim_mill_pyramid_subtype =40
sim_mill_cylinder_subtype =41
sim_mill_disc_subtype =42
sim_mill_cone_subtype =42
# No sub-type
sim_object_no_subtype =200
#Scene object main properties (serialized)
sim_objectspecialproperty_collidable =0x0001
sim_objectspecialproperty_measurable =0x0002
#reserved =0x0004
#reserved =0x0008
sim_objectspecialproperty_detectable_ultrasonic =0x0010
sim_objectspecialproperty_detectable_infrared =0x0020
sim_objectspecialproperty_detectable_laser =0x0040
sim_objectspecialproperty_detectable_inductive =0x0080
sim_objectspecialproperty_detectable_capacitive =0x0100
sim_objectspecialproperty_renderable =0x0200
sim_objectspecialproperty_detectable_all =sim_objectspecialproperty_detectable_ultrasonic|sim_objectspecialproperty_detectable_infrared|sim_objectspecialproperty_detectable_laser|sim_objectspecialproperty_detectable_inductive|sim_objectspecialproperty_detectable_capacitive
sim_objectspecialproperty_cuttable =0x0400
sim_objectspecialproperty_pathplanning_ignored =0x0800
# Model properties (serialized)
sim_modelproperty_not_collidable =0x0001
sim_modelproperty_not_measurable =0x0002
sim_modelproperty_not_renderable =0x0004
sim_modelproperty_not_detectable =0x0008
sim_modelproperty_not_cuttable =0x0010
sim_modelproperty_not_dynamic =0x0020
sim_modelproperty_not_respondable =0x0040 # cannot be selected if sim_modelproperty_not_dynamic is not selected
sim_modelproperty_not_reset =0x0080 # Model is not reset at simulation end. This flag is cleared at simulation end
sim_modelproperty_not_visible =0x0100 # Whole model is invisible independent of local visibility settings
sim_modelproperty_not_model =0xf000 # object is not a model
# Check the documentation instead of comments below!!
# Following messages are dispatched to the Lua-message container
sim_message_ui_button_state_change =0 # a UI button slider etc. changed (due to a user's action). aux[0]=UI handle aux[1]=button handle aux[2]=button attributes aux[3]=slider position (if slider)
sim_message_reserved9 =1 # Do not use
sim_message_object_selection_changed=2
sim_message_reserved10 =3 # do not use
sim_message_model_loaded =4
sim_message_reserved11 =5 # do not use
sim_message_keypress =6 # a key was pressed while the focus was on a page (aux[0]=key aux[1]=ctrl and shift key state)
sim_message_bannerclicked =7 # a banner was clicked (aux[0]=banner ID)
# Following messages are dispatched only to the C-API (not available from Lua)
sim_message_for_c_api_only_start =0x100 # Do not use
sim_message_reserved1 =0x101 # Do not use
sim_message_reserved2 =0x102 # Do not use
sim_message_reserved3 =0x103 # Do not use
sim_message_eventcallback_scenesave =0x104 # about to save a scene
sim_message_eventcallback_modelsave =0x105 # about to save a model (current selection will be saved)
sim_message_eventcallback_moduleopen =0x106 # called when simOpenModule in Lua is called
sim_message_eventcallback_modulehandle =0x107 # called when simHandleModule in Lua is called with argument false
sim_message_eventcallback_moduleclose =0x108 # called when simCloseModule in Lua is called
sim_message_reserved4 =0x109 # Do not use
sim_message_reserved5 =0x10a # Do not use
sim_message_reserved6 =0x10b # Do not use
sim_message_reserved7 =0x10c # Do not use
sim_message_eventcallback_instancepass =0x10d # Called once every main application loop pass. auxiliaryData[0] contains event flags of events that happened since last time
sim_message_eventcallback_broadcast =0x10e
sim_message_eventcallback_imagefilter_enumreset =0x10f
sim_message_eventcallback_imagefilter_enumerate =0x110
sim_message_eventcallback_imagefilter_adjustparams =0x111
sim_message_eventcallback_imagefilter_reserved =0x112
sim_message_eventcallback_imagefilter_process =0x113
sim_message_eventcallback_reserved1 =0x114 # do not use
sim_message_eventcallback_reserved2 =0x115 # do not use
sim_message_eventcallback_reserved3 =0x116 # do not use
sim_message_eventcallback_reserved4 =0x117 # do not use
sim_message_eventcallback_abouttoundo =0x118 # the undo button was hit and a previous state is about to be restored
sim_message_eventcallback_undoperformed =0x119 # the undo button was hit and a previous state restored
sim_message_eventcallback_abouttoredo =0x11a # the redo button was hit and a future state is about to be restored
sim_message_eventcallback_redoperformed =0x11b # the redo button was hit and a future state restored
sim_message_eventcallback_scripticondblclick =0x11c # scipt icon was double clicked. (aux[0]=object handle associated with script set replyData[0] to 1 if script should not be opened)
sim_message_eventcallback_simulationabouttostart =0x11d
sim_message_eventcallback_simulationended =0x11e
sim_message_eventcallback_reserved5 =0x11f # do not use
sim_message_eventcallback_keypress =0x120 # a key was pressed while the focus was on a page (aux[0]=key aux[1]=ctrl and shift key state)
sim_message_eventcallback_modulehandleinsensingpart =0x121 # called when simHandleModule in Lua is called with argument true
sim_message_eventcallback_renderingpass =0x122 # called just before the scene is rendered
sim_message_eventcallback_bannerclicked =0x123 # called when a banner was clicked (aux[0]=banner ID)
sim_message_eventcallback_menuitemselected =0x124 # auxiliaryData[0] indicates the handle of the item auxiliaryData[1] indicates the state of the item
sim_message_eventcallback_refreshdialogs =0x125 # aux[0]=refresh degree (0=light 1=medium 2=full)
sim_message_eventcallback_sceneloaded =0x126
sim_message_eventcallback_modelloaded =0x127
sim_message_eventcallback_instanceswitch =0x128
sim_message_eventcallback_guipass =0x129
sim_message_eventcallback_mainscriptabouttobecalled =0x12a
sim_message_eventcallback_rmlposition =0x12b #the command simRMLPosition was called. The appropriate plugin should handle the call
sim_message_eventcallback_rmlvelocity =0x12c # the command simRMLVelocity was called. The appropriate plugin should handle the call
sim_message_simulation_start_resume_request =0x1000
sim_message_simulation_pause_request =0x1001
sim_message_simulation_stop_request =0x1002
# Scene object properties. Combine with the | operator
sim_objectproperty_reserved1 =0x0000
sim_objectproperty_reserved2 =0x0001
sim_objectproperty_reserved3 =0x0002
sim_objectproperty_reserved4 =0x0003
sim_objectproperty_reserved5 =0x0004 # formely sim_objectproperty_visible
sim_objectproperty_reserved6 =0x0008 # formely sim_objectproperty_wireframe
sim_objectproperty_collapsed =0x0010
sim_objectproperty_selectable =0x0020
sim_objectproperty_reserved7 =0x0040
sim_objectproperty_selectmodelbaseinstead =0x0080
sim_objectproperty_dontshowasinsidemodel =0x0100
# reserved =0x0200
sim_objectproperty_canupdatedna =0x0400
sim_objectproperty_selectinvisible =0x0800
sim_objectproperty_depthinvisible =0x1000
# type of arguments (input and output) for custom lua commands
sim_lua_arg_nil =0
sim_lua_arg_bool =1
sim_lua_arg_int =2
sim_lua_arg_float =3
sim_lua_arg_string =4
sim_lua_arg_invalid =5
sim_lua_arg_table =8
# custom user interface properties. Values are serialized.
sim_ui_property_visible =0x0001
sim_ui_property_visibleduringsimulationonly =0x0002
sim_ui_property_moveable =0x0004
sim_ui_property_relativetoleftborder =0x0008
sim_ui_property_relativetotopborder =0x0010
sim_ui_property_fixedwidthfont =0x0020
sim_ui_property_systemblock =0x0040
sim_ui_property_settocenter =0x0080
sim_ui_property_rolledup =0x0100
sim_ui_property_selectassociatedobject =0x0200
sim_ui_property_visiblewhenobjectselected =0x0400
# button properties. Values are serialized.
sim_buttonproperty_button =0x0000
sim_buttonproperty_label =0x0001
sim_buttonproperty_slider =0x0002
sim_buttonproperty_editbox =0x0003
sim_buttonproperty_staydown =0x0008
sim_buttonproperty_enabled =0x0010
sim_buttonproperty_borderless =0x0020
sim_buttonproperty_horizontallycentered =0x0040
sim_buttonproperty_ignoremouse =0x0080
sim_buttonproperty_isdown =0x0100
sim_buttonproperty_transparent =0x0200
sim_buttonproperty_nobackgroundcolor =0x0400
sim_buttonproperty_rollupaction =0x0800
sim_buttonproperty_closeaction =0x1000
sim_buttonproperty_verticallycentered =0x2000
sim_buttonproperty_downupevent =0x4000
# Simulation status
sim_simulation_stopped =0x00 # Simulation is stopped
sim_simulation_paused =0x08 # Simulation is paused
sim_simulation_advancing =0x10 # Simulation is advancing
sim_simulation_advancing_firstafterstop =sim_simulation_advancing|0x00 # First simulation pass (1x)
sim_simulation_advancing_running =sim_simulation_advancing|0x01 # Normal simulation pass (>=1x)
# reserved =sim_simulation_advancing|0x02
sim_simulation_advancing_lastbeforepause =sim_simulation_advancing|0x03 # Last simulation pass before pause (1x)
sim_simulation_advancing_firstafterpause =sim_simulation_advancing|0x04 # First simulation pass after pause (1x)
sim_simulation_advancing_abouttostop =sim_simulation_advancing|0x05 # "Trying to stop" simulation pass (>=1x)
sim_simulation_advancing_lastbeforestop =sim_simulation_advancing|0x06 # Last simulation pass (1x)
# Script execution result (first return value)
sim_script_no_error =0
sim_script_main_script_nonexistent =1
sim_script_main_script_not_called =2
sim_script_reentrance_error =4
sim_script_lua_error =8
sim_script_call_error =16
# Script types (serialized!)
sim_scripttype_mainscript =0
sim_scripttype_childscript =1
sim_scripttype_jointctrlcallback =4
sim_scripttype_contactcallback =5
sim_scripttype_customizationscript =6
sim_scripttype_generalcallback =7
# API call error messages
sim_api_errormessage_ignore =0 # does not memorize nor output errors
sim_api_errormessage_report =1 # memorizes errors (default for C-API calls)
sim_api_errormessage_output =2 # memorizes and outputs errors (default for Lua-API calls)
# special argument of some functions
sim_handle_all =-2
sim_handle_all_except_explicit =-3
sim_handle_self =-4
sim_handle_main_script =-5
sim_handle_tree =-6
sim_handle_chain =-7
sim_handle_single =-8
sim_handle_default =-9
sim_handle_all_except_self =-10
sim_handle_parent =-11
# special handle flags
sim_handleflag_assembly =0x400000
sim_handleflag_model =0x800000
# distance calculation methods (serialized)
sim_distcalcmethod_dl =0
sim_distcalcmethod_dac =1
sim_distcalcmethod_max_dl_dac =2
sim_distcalcmethod_dl_and_dac =3
sim_distcalcmethod_sqrt_dl2_and_dac2=4
sim_distcalcmethod_dl_if_nonzero =5
sim_distcalcmethod_dac_if_nonzero =6
# Generic dialog styles
sim_dlgstyle_message =0
sim_dlgstyle_input =1
sim_dlgstyle_ok =2
sim_dlgstyle_ok_cancel =3
sim_dlgstyle_yes_no =4
sim_dlgstyle_dont_center =32# can be combined with one of above values. Only with this flag can the position of the related UI be set just after dialog creation
# Generic dialog return values
sim_dlgret_still_open =0
sim_dlgret_ok =1
sim_dlgret_cancel =2
sim_dlgret_yes =3
sim_dlgret_no =4
# Path properties
sim_pathproperty_show_line =0x0001
sim_pathproperty_show_orientation =0x0002
sim_pathproperty_closed_path =0x0004
sim_pathproperty_automatic_orientation =0x0008
sim_pathproperty_invert_velocity =0x0010
sim_pathproperty_infinite_acceleration =0x0020
sim_pathproperty_flat_path =0x0040
sim_pathproperty_show_position =0x0080
sim_pathproperty_auto_velocity_profile_translation =0x0100
sim_pathproperty_auto_velocity_profile_rotation =0x0200
sim_pathproperty_endpoints_at_zero =0x0400
sim_pathproperty_keep_x_up =0x0800
# drawing objects
# following are mutually exclusive
sim_drawing_points =0 # 3 values per point (point size in pixels)
sim_drawing_lines =1 # 6 values per line (line size in pixels)
sim_drawing_triangles =2 # 9 values per triangle
sim_drawing_trianglepoints =3 # 6 values per point (3 for triangle position 3 for triangle normal vector) (triangle size in meters)
sim_drawing_quadpoints =4 # 6 values per point (3 for quad position 3 for quad normal vector) (quad size in meters)
sim_drawing_discpoints =5 # 6 values per point (3 for disc position 3 for disc normal vector) (disc size in meters)
sim_drawing_cubepoints =6 # 6 values per point (3 for cube position 3 for cube normal vector) (cube size in meters)
sim_drawing_spherepoints =7 # 3 values per point (sphere size in meters)
# following can be or-combined
sim_drawing_itemcolors =0x00020 # +3 values per item (each item has its own ambient color (rgb values)).
# Mutually exclusive with sim_drawing_vertexcolors
sim_drawing_vertexcolors =0x00040 # +3 values per vertex (each vertex has its own ambient color (rgb values). Only for sim_drawing_lines (+6) and for sim_drawing_triangles(+9)). Mutually exclusive with sim_drawing_itemcolors
sim_drawing_itemsizes =0x00080 # +1 value per item (each item has its own size). Not for sim_drawing_triangles
sim_drawing_backfaceculling =0x00100 # back faces are not displayed for all items
sim_drawing_wireframe =0x00200 # all items displayed in wireframe
sim_drawing_painttag =0x00400 # all items are tagged as paint (for additinal processing at a later stage)
sim_drawing_followparentvisibility =0x00800 # if the object is associated with a scene object then it follows that visibility otherwise it is always visible
sim_drawing_cyclic =0x01000 # if the max item count was reached then the first items are overwritten.
sim_drawing_50percenttransparency =0x02000 # the drawing object will be 50% transparent
sim_drawing_25percenttransparency =0x04000 # the drawing object will be 25% transparent
sim_drawing_12percenttransparency =0x08000 # the drawing object will be 12.5% transparent
sim_drawing_emissioncolor =0x10000 # When used in combination with sim_drawing_itemcolors or sim_drawing_vertexcolors then the specified colors will be for the emissive component
sim_drawing_facingcamera =0x20000 # Only for trianglepoints quadpoints discpoints and cubepoints. If specified the normal verctor is calculated to face the camera (each item data requires 3 values less)
sim_drawing_overlay =0x40000 # When specified objects are always drawn on top of "regular objects"
sim_drawing_itemtransparency =0x80000 # +1 value per item (each item has its own transparency value (0-1)). Not compatible with sim_drawing_vertexcolors
# banner values
# following can be or-combined
sim_banner_left =0x00001 # Banners display on the left of the specified point
sim_banner_right =0x00002 # Banners display on the right of the specified point
sim_banner_nobackground =0x00004 # Banners have no background rectangle
sim_banner_overlay =0x00008 # When specified banners are always drawn on top of "regular objects"
sim_banner_followparentvisibility =0x00010 # if the object is associated with a scene object then it follows that visibility otherwise it is always visible
sim_banner_clickselectsparent =0x00020 # if the object is associated with a scene object then clicking the banner will select the scene object
sim_banner_clicktriggersevent =0x00040 # if the banner is clicked an event is triggered (sim_message_eventcallback_bannerclicked and sim_message_bannerclicked are generated)
sim_banner_facingcamera =0x00080 # If specified the banner will always face the camera by rotating around the banner's vertical axis (y-axis)
sim_banner_fullyfacingcamera =0x00100 # If specified the banner will always fully face the camera (the banner's orientation is same as the camera looking at it)
sim_banner_backfaceculling =0x00200 # If specified the banner will only be visible from one side
sim_banner_keepsamesize =0x00400 # If specified the banner will always appear in the same size. In that case size represents the character height in pixels
sim_banner_bitmapfont =0x00800 # If specified a fixed-size bitmap font is used. The text will also always fully face the camera and be right
# to the specified position. Bitmap fonts are not clickable
# particle objects following are mutually exclusive
sim_particle_points1 =0 # 6 values per point (pt1 and pt2. Pt1 is start position pt2-pt1 is the initial velocity vector). i
#Point is 1 pixel big. Only appearance is a point internally handled as a perfect sphere
sim_particle_points2 =1 # 6 values per point. Point is 2 pixel big. Only appearance is a point internally handled as a perfect sphere
sim_particle_points4 =2 # 6 values per point. Point is 4 pixel big. Only appearance is a point internally handled as a perfect sphere
sim_particle_roughspheres =3 # 6 values per sphere. Only appearance is rough. Internally a perfect sphere
sim_particle_spheres =4 # 6 values per sphere. Internally a perfect sphere
# following can be or-combined
sim_particle_respondable1to4 =0x0020 # the particles are respondable against shapes (against all objects that have at least one bit 1-4 activated in the global respondable mask)
sim_particle_respondable5to8 =0x0040 # the particles are respondable against shapes (against all objects that have at least one bit 5-8 activated in the global respondable mask)
sim_particle_particlerespondable =0x0080 # the particles are respondable against each other
sim_particle_ignoresgravity =0x0100 # the particles ignore the effect of gravity. Not compatible with sim_particle_water
sim_particle_invisible =0x0200 # the particles are invisible
sim_particle_itemsizes =0x0400 # +1 value per particle (each particle can have a different size)
sim_particle_itemdensities =0x0800 # +1 value per particle (each particle can have a different density)
sim_particle_itemcolors =0x1000 # +3 values per particle (each particle can have a different color)
sim_particle_cyclic =0x2000 # if the max item count was reached then the first items are overwritten.
sim_particle_emissioncolor =0x4000 # When used in combination with sim_particle_itemcolors then the specified colors will be for the emissive component
sim_particle_water =0x8000 # the particles are water particles (no weight in the water (i.e. when z<0)). Not compatible with sim_particle_ignoresgravity
sim_particle_painttag =0x10000 # The particles can be seen by vision sensors (sim_particle_invisible must not be set)
# custom user interface menu attributes
sim_ui_menu_title =1
sim_ui_menu_minimize =2
sim_ui_menu_close =4
sim_ui_menu_systemblock =8
# Boolean parameters
sim_boolparam_hierarchy_visible =0
sim_boolparam_console_visible =1
sim_boolparam_collision_handling_enabled =2
sim_boolparam_distance_handling_enabled =3
sim_boolparam_ik_handling_enabled =4
sim_boolparam_gcs_handling_enabled =5
sim_boolparam_dynamics_handling_enabled =6
sim_boolparam_joint_motion_handling_enabled =7
sim_boolparam_path_motion_handling_enabled =8
sim_boolparam_proximity_sensor_handling_enabled =9
sim_boolparam_vision_sensor_handling_enabled =10
sim_boolparam_mill_handling_enabled =11
sim_boolparam_browser_visible =12
sim_boolparam_scene_and_model_load_messages =13
sim_reserved0 =14
sim_boolparam_shape_textures_are_visible =15
sim_boolparam_display_enabled =16
sim_boolparam_infotext_visible =17
sim_boolparam_statustext_open =18
sim_boolparam_fog_enabled =19
sim_boolparam_rml2_available =20
sim_boolparam_rml4_available =21
sim_boolparam_mirrors_enabled =22
sim_boolparam_aux_clip_planes_enabled =23
sim_boolparam_full_model_copy_from_api =24
sim_boolparam_realtime_simulation =25
sim_boolparam_force_show_wireless_emission =27
sim_boolparam_force_show_wireless_reception =28
sim_boolparam_video_recording_triggered =29
sim_boolparam_threaded_rendering_enabled =32
sim_boolparam_fullscreen =33
sim_boolparam_headless =34
sim_boolparam_hierarchy_toolbarbutton_enabled =35
sim_boolparam_browser_toolbarbutton_enabled =36
sim_boolparam_objectshift_toolbarbutton_enabled =37
sim_boolparam_objectrotate_toolbarbutton_enabled=38
sim_boolparam_force_calcstruct_all_visible =39
sim_boolparam_force_calcstruct_all =40
sim_boolparam_exit_request =41
sim_boolparam_play_toolbarbutton_enabled =42
sim_boolparam_pause_toolbarbutton_enabled =43
sim_boolparam_stop_toolbarbutton_enabled =44
sim_boolparam_waiting_for_trigger =45
# Integer parameters
sim_intparam_error_report_mode =0 # Check sim_api_errormessage_... constants above for valid values
sim_intparam_program_version =1 # e.g Version 2.1.4 --> 20104. Can only be read
sim_intparam_instance_count =2 # do not use anymore (always returns 1 since CoppeliaSim 2.5.11)
sim_intparam_custom_cmd_start_id =3 # can only be read
sim_intparam_compilation_version =4 # 0=evaluation version 1=full version 2=player version. Can only be read
sim_intparam_current_page =5
sim_intparam_flymode_camera_handle =6 # can only be read
sim_intparam_dynamic_step_divider =7 # can only be read
sim_intparam_dynamic_engine =8 # 0=Bullet 1=ODE. 2=Vortex.
sim_intparam_server_port_start =9 # can only be read
sim_intparam_server_port_range =10 # can only be read
sim_intparam_visible_layers =11
sim_intparam_infotext_style =12
sim_intparam_settings =13
sim_intparam_edit_mode_type =14 # can only be read
sim_intparam_server_port_next =15 # is initialized at sim_intparam_server_port_start
sim_intparam_qt_version =16 # version of the used Qt framework
sim_intparam_event_flags_read =17 # can only be read
sim_intparam_event_flags_read_clear =18 # can only be read
sim_intparam_platform =19 # can only be read
sim_intparam_scene_unique_id =20 # can only be read
sim_intparam_work_thread_count =21
sim_intparam_mouse_x =22
sim_intparam_mouse_y =23
sim_intparam_core_count =24
sim_intparam_work_thread_calc_time_ms =25
sim_intparam_idle_fps =26
sim_intparam_prox_sensor_select_down =27
sim_intparam_prox_sensor_select_up =28
sim_intparam_stop_request_counter =29
sim_intparam_program_revision =30
sim_intparam_mouse_buttons =31
sim_intparam_dynamic_warning_disabled_mask =32
sim_intparam_simulation_warning_disabled_mask =33
sim_intparam_scene_index =34
sim_intparam_motionplanning_seed =35
sim_intparam_speedmodifier =36
# Float parameters
sim_floatparam_rand=0 # random value (0.0-1.0)
sim_floatparam_simulation_time_step =1
sim_floatparam_stereo_distance =2
# String parameters
sim_stringparam_application_path=0 # path of CoppeliaSim's executable
sim_stringparam_video_filename=1
sim_stringparam_app_arg1 =2
sim_stringparam_app_arg2 =3
sim_stringparam_app_arg3 =4
sim_stringparam_app_arg4 =5
sim_stringparam_app_arg5 =6
sim_stringparam_app_arg6 =7
sim_stringparam_app_arg7 =8
sim_stringparam_app_arg8 =9
sim_stringparam_app_arg9 =10
sim_stringparam_scene_path_and_name =13
# Array parameters
sim_arrayparam_gravity =0
sim_arrayparam_fog =1
sim_arrayparam_fog_color =2
sim_arrayparam_background_color1=3
sim_arrayparam_background_color2=4
sim_arrayparam_ambient_light =5
sim_arrayparam_random_euler =6
sim_objintparam_visibility_layer= 10
sim_objfloatparam_abs_x_velocity= 11
sim_objfloatparam_abs_y_velocity= 12
sim_objfloatparam_abs_z_velocity= 13
sim_objfloatparam_abs_rot_velocity= 14
sim_objfloatparam_objbbox_min_x= 15
sim_objfloatparam_objbbox_min_y= 16
sim_objfloatparam_objbbox_min_z= 17
sim_objfloatparam_objbbox_max_x= 18
sim_objfloatparam_objbbox_max_y= 19
sim_objfloatparam_objbbox_max_z= 20
sim_objfloatparam_modelbbox_min_x= 21
sim_objfloatparam_modelbbox_min_y= 22
sim_objfloatparam_modelbbox_min_z= 23
sim_objfloatparam_modelbbox_max_x= 24
sim_objfloatparam_modelbbox_max_y= 25
sim_objfloatparam_modelbbox_max_z= 26
sim_objintparam_collection_self_collision_indicator= 27
sim_objfloatparam_transparency_offset= 28
sim_objintparam_child_role= 29
sim_objintparam_parent_role= 30
sim_objintparam_manipulation_permissions= 31
sim_objintparam_illumination_handle= 32
sim_visionfloatparam_near_clipping= 1000
sim_visionfloatparam_far_clipping= 1001
sim_visionintparam_resolution_x= 1002
sim_visionintparam_resolution_y= 1003
sim_visionfloatparam_perspective_angle= 1004
sim_visionfloatparam_ortho_size= 1005
sim_visionintparam_disabled_light_components= 1006
sim_visionintparam_rendering_attributes= 1007
sim_visionintparam_entity_to_render= 1008
sim_visionintparam_windowed_size_x= 1009
sim_visionintparam_windowed_size_y= 1010
sim_visionintparam_windowed_pos_x= 1011
sim_visionintparam_windowed_pos_y= 1012
sim_visionintparam_pov_focal_blur= 1013
sim_visionfloatparam_pov_blur_distance= 1014
sim_visionfloatparam_pov_aperture= 1015
sim_visionintparam_pov_blur_sampled= 1016
sim_visionintparam_render_mode= 1017
sim_jointintparam_motor_enabled= 2000
sim_jointintparam_ctrl_enabled= 2001
sim_jointfloatparam_pid_p= 2002
sim_jointfloatparam_pid_i= 2003
sim_jointfloatparam_pid_d= 2004
sim_jointfloatparam_intrinsic_x= 2005
sim_jointfloatparam_intrinsic_y= 2006
sim_jointfloatparam_intrinsic_z= 2007
sim_jointfloatparam_intrinsic_qx= 2008
sim_jointfloatparam_intrinsic_qy= 2009
sim_jointfloatparam_intrinsic_qz= 2010
sim_jointfloatparam_intrinsic_qw= 2011
sim_jointfloatparam_velocity= 2012
sim_jointfloatparam_spherical_qx= 2013
sim_jointfloatparam_spherical_qy= 2014
sim_jointfloatparam_spherical_qz= 2015
sim_jointfloatparam_spherical_qw= 2016
sim_jointfloatparam_upper_limit= 2017
sim_jointfloatparam_kc_k= 2018
sim_jointfloatparam_kc_c= 2019
sim_jointfloatparam_ik_weight= 2021
sim_jointfloatparam_error_x= 2022
sim_jointfloatparam_error_y= 2023
sim_jointfloatparam_error_z= 2024
sim_jointfloatparam_error_a= 2025
sim_jointfloatparam_error_b= 2026
sim_jointfloatparam_error_g= 2027
sim_jointfloatparam_error_pos= 2028
sim_jointfloatparam_error_angle= 2029
sim_jointintparam_velocity_lock= 2030
sim_jointintparam_vortex_dep_handle= 2031
sim_jointfloatparam_vortex_dep_multiplication= 2032
sim_jointfloatparam_vortex_dep_offset= 2033
sim_shapefloatparam_init_velocity_x= 3000
sim_shapefloatparam_init_velocity_y= 3001
sim_shapefloatparam_init_velocity_z= 3002
sim_shapeintparam_static= 3003
sim_shapeintparam_respondable= 3004
sim_shapefloatparam_mass= 3005
sim_shapefloatparam_texture_x= 3006
sim_shapefloatparam_texture_y= 3007
sim_shapefloatparam_texture_z= 3008
sim_shapefloatparam_texture_a= 3009
sim_shapefloatparam_texture_b= 3010
sim_shapefloatparam_texture_g= 3011
sim_shapefloatparam_texture_scaling_x= 3012
sim_shapefloatparam_texture_scaling_y= 3013
sim_shapeintparam_culling= 3014
sim_shapeintparam_wireframe= 3015
sim_shapeintparam_compound= 3016
sim_shapeintparam_convex= 3017
sim_shapeintparam_convex_check= 3018
sim_shapeintparam_respondable_mask= 3019
sim_shapefloatparam_init_velocity_a= 3020
sim_shapefloatparam_init_velocity_b= 3021
sim_shapefloatparam_init_velocity_g= 3022
sim_shapestringparam_color_name= 3023
sim_shapeintparam_edge_visibility= 3024
sim_shapefloatparam_shading_angle= 3025
sim_shapefloatparam_edge_angle= 3026
sim_shapeintparam_edge_borders_hidden= 3027
sim_proxintparam_ray_invisibility= 4000
sim_forcefloatparam_error_x= 5000
sim_forcefloatparam_error_y= 5001
sim_forcefloatparam_error_z= 5002
sim_forcefloatparam_error_a= 5003
sim_forcefloatparam_error_b= 5004
sim_forcefloatparam_error_g= 5005
sim_forcefloatparam_error_pos= 5006
sim_forcefloatparam_error_angle= 5007
sim_lightintparam_pov_casts_shadows= 8000
sim_cameraintparam_disabled_light_components= 9000
sim_camerafloatparam_perspective_angle= 9001
sim_camerafloatparam_ortho_size= 9002
sim_cameraintparam_rendering_attributes= 9003
sim_cameraintparam_pov_focal_blur= 9004
sim_camerafloatparam_pov_blur_distance= 9005
sim_camerafloatparam_pov_aperture= 9006
sim_cameraintparam_pov_blur_samples= 9007
sim_dummyintparam_link_type= 10000
sim_mirrorfloatparam_width= 12000
sim_mirrorfloatparam_height= 12001
sim_mirrorfloatparam_reflectance= 12002
sim_mirrorintparam_enable= 12003
sim_pplanfloatparam_x_min= 20000
sim_pplanfloatparam_x_range= 20001
sim_pplanfloatparam_y_min= 20002
sim_pplanfloatparam_y_range= 20003
sim_pplanfloatparam_z_min= 20004
sim_pplanfloatparam_z_range= 20005
sim_pplanfloatparam_delta_min= 20006
sim_pplanfloatparam_delta_range= 20007
sim_mplanintparam_nodes_computed= 25000
sim_mplanintparam_prepare_nodes= 25001
sim_mplanintparam_clear_nodes= 25002
# User interface elements
sim_gui_menubar =0x0001
sim_gui_popups =0x0002
sim_gui_toolbar1 =0x0004
sim_gui_toolbar2 =0x0008
sim_gui_hierarchy =0x0010
sim_gui_infobar =0x0020
sim_gui_statusbar =0x0040
sim_gui_scripteditor =0x0080
sim_gui_scriptsimulationparameters =0x0100
sim_gui_dialogs =0x0200
sim_gui_browser =0x0400
sim_gui_all =0xffff
# Joint modes
sim_jointmode_passive =0
sim_jointmode_motion =1
sim_jointmode_ik =2
sim_jointmode_ikdependent =3
sim_jointmode_dependent =4
sim_jointmode_force =5
# Navigation and selection modes with the mouse. Lower byte values are mutually exclusive upper byte bits can be combined
sim_navigation_passive =0x0000
sim_navigation_camerashift =0x0001
sim_navigation_camerarotate =0x0002
sim_navigation_camerazoom =0x0003
sim_navigation_cameratilt =0x0004
sim_navigation_cameraangle =0x0005
sim_navigation_camerafly =0x0006
sim_navigation_objectshift =0x0007
sim_navigation_objectrotate =0x0008
sim_navigation_reserved2 =0x0009
sim_navigation_reserved3 =0x000A
sim_navigation_jointpathtest =0x000B
sim_navigation_ikmanip =0x000C
sim_navigation_objectmultipleselection =0x000D
# Bit-combine following values and add them to one of above's values for a valid navigation mode
sim_navigation_reserved4 =0x0100
sim_navigation_clickselection =0x0200
sim_navigation_ctrlselection =0x0400
sim_navigation_shiftselection =0x0800
sim_navigation_camerazoomwheel =0x1000
sim_navigation_camerarotaterightbutton =0x2000
#Remote API constants
SIMX_VERSION =0
# Remote API message header structure
SIMX_HEADER_SIZE =18
simx_headeroffset_crc =0 # 1 simxUShort. Generated by the client or server. The CRC for the message
simx_headeroffset_version =2 # 1 byte. Generated by the client or server. The version of the remote API software
simx_headeroffset_message_id =3 # 1 simxInt. Generated by the client (and used in a reply by the server)
simx_headeroffset_client_time =7 # 1 simxInt. Client time stamp generated by the client (and sent back by the server)
simx_headeroffset_server_time =11 # 1 simxInt. Generated by the server when a reply is generated. The server timestamp
simx_headeroffset_scene_id =15 # 1 simxUShort. Generated by the server. A unique ID identifying the scene currently displayed
simx_headeroffset_server_state =17 # 1 byte. Generated by the server. Bit coded 0 set --> simulation not stopped 1 set --> simulation paused 2 set --> real-time switch on 3-5 edit mode type (0=no edit mode 1=triangle 2=vertex 3=edge 4=path 5=UI)
# Remote API command header
SIMX_SUBHEADER_SIZE =26
simx_cmdheaderoffset_mem_size =0 # 1 simxInt. Generated by the client or server. The buffer size of the command.
simx_cmdheaderoffset_full_mem_size =4 # 1 simxInt. Generated by the client or server. The full buffer size of the command (applies to split chunks).
simx_cmdheaderoffset_pdata_offset0 =8 # 1 simxUShort. Generated by the client or server. The amount of data that is part of the command identification.
simx_cmdheaderoffset_pdata_offset1 =10 # 1 simxInt. Generated by the client or server. The amount of shift of the pure data buffer (applies to split chunks).
simx_cmdheaderoffset_cmd=14 # 1 simxInt. Generated by the client (and used in a reply by the server). The command combined with the operation mode of the command.
simx_cmdheaderoffset_delay_or_split =18 # 1 simxUShort. Generated by the client or server. The amount of delay in ms of a continuous command or the max. pure data size to send at once (applies to split commands).
simx_cmdheaderoffset_sim_time =20 # 1 simxInt. Generated by the server. The simulation time (in ms) when the command was executed (or 0 if simulation is not running)
simx_cmdheaderoffset_status =24 # 1 byte. Generated by the server. (1 bit 0 is set --> error in function execution on server side). The client writes bit 1 if command cannot be overwritten
simx_cmdheaderoffset_reserved =25 # 1 byte. Not yet used
# Regular operation modes
simx_opmode_oneshot =0x000000 # sends command as one chunk. Reply will also come as one chunk. Doesn't wait for the reply.
simx_opmode_blocking =0x010000 # sends command as one chunk. Reply will also come as one chunk. Waits for the reply (_REPLY_WAIT_TIMEOUT_IN_MS is the timeout).
simx_opmode_oneshot_wait =0x010000 # sends command as one chunk. Reply will also come as one chunk. Waits for the reply (_REPLY_WAIT_TIMEOUT_IN_MS is the timeout).
simx_opmode_continuous =0x020000
simx_opmode_streaming =0x020000 # sends command as one chunk. Command will be stored on the server and always executed
#(every x ms (as far as possible) where x can be 0-65535. just add x to opmode_continuous).
# A reply will be sent continuously each time as one chunk. Doesn't wait for the reply.
# Operation modes for heavy data
simx_opmode_oneshot_split =0x030000 # sends command as several chunks (max chunk size is x bytes where x can be _MIN_SPLIT_AMOUNT_IN_BYTES-65535. Just add x to opmode_oneshot_split). Reply will also come as several chunks. Doesn't wait for the reply.
simx_opmode_continuous_split =0x040000
simx_opmode_streaming_split =0x040000 # sends command as several chunks (max chunk size is x bytes where x can be _MIN_SPLIT_AMOUNT_IN_BYTES-65535. Just add x to opmode_continuous_split). Command will be stored on the server and always executed. A reply will be sent continuously each time as several chunks. Doesn't wait for the reply.
# Special operation modes
simx_opmode_discontinue =0x050000 # removes and cancels all commands stored on the client or server side (also continuous commands)
simx_opmode_buffer =0x060000 # doesn't send anything but checks if a reply for the given command is available in the input buffer (i.e. previously received from the server)
simx_opmode_remove =0x070000 # doesn't send anything and doesn't return any specific value. It just erases a similar command reply in the inbox (to free some memory)
# Command return codes
simx_return_ok =0x000000
simx_return_novalue_flag =0x000001 # input buffer doesn't contain the specified command
simx_return_timeout_flag =0x000002 # command reply not received in time for opmode_oneshot_wait operation mode
simx_return_illegal_opmode_flag =0x000004 # command doesn't support the specified operation mode
simx_return_remote_error_flag =0x000008 # command caused an error on the server side
simx_return_split_progress_flag =0x000010 # previous similar command not yet fully processed (applies to opmode_oneshot_split operation modes)
simx_return_local_error_flag =0x000020 # command caused an error on the client side
simx_return_initialize_error_flag =0x000040 # simxStart was not yet called
# Following for backward compatibility (same as above)
simx_error_noerror =0x000000
simx_error_novalue_flag =0x000001 # input buffer doesn't contain the specified command
simx_error_timeout_flag =0x000002 # command reply not received in time for opmode_oneshot_wait operation mode
simx_error_illegal_opmode_flag =0x000004 # command doesn't support the specified operation mode
simx_error_remote_error_flag =0x000008 # command caused an error on the server side
simx_error_split_progress_flag =0x000010 # previous similar command not yet fully processed (applies to opmode_oneshot_split operation modes)
simx_error_local_error_flag =0x000020 # command caused an error on the client side
simx_error_initialize_error_flag =0x000040 # simxStart was not yet called

@ -0,0 +1,58 @@
# This small example illustrates how to use the remote API
# synchronous mode. The synchronous mode needs to be
# pre-enabled on the server side. You would do this by
# starting the server (e.g. in a child script) with:
#
# simRemoteApi.start(19999,1300,false,true)
#
# But in this example we try to connect on port
# 19997 where there should be a continuous remote API
# server service already running and pre-enabled for
# synchronous mode.
#
#
# IMPORTANT: for each successful call to simxStart, there
# should be a corresponding call to simxFinish at the end!
try:
import sim
except:
print ('--------------------------------------------------------------')
print ('"sim.py" could not be imported. This means very probably that')
print ('either "sim.py" or the remoteApi library could not be found.')
print ('Make sure both are in the same folder as this file,')
print ('or appropriately adjust the file "sim.py"')
print ('--------------------------------------------------------------')
print ('')
import time
import sys
print ('Program started')
sim.simxFinish(-1) # just in case, close all opened connections
clientID=sim.simxStart('127.0.0.1',19997,True,True,5000,5) # Connect to CoppeliaSim
if clientID!=-1:
print ('Connected to remote API server')
# enable the synchronous mode on the client:
sim.simxSynchronous(clientID,True)
# start the simulation:
sim.simxStartSimulation(clientID,sim.simx_opmode_blocking)
# Now step a few times:
for i in range(1,10):
if sys.version_info[0] == 3:
input('Press <enter> key to step the simulation!')
else:
raw_input('Press <enter> key to step the simulation!')
sim.simxSynchronousTrigger(clientID);
# stop the simulation:
sim.simxStopSimulation(clientID,sim.simx_opmode_blocking)
# Now close the connection to CoppeliaSim:
sim.simxFinish(clientID)
else:
print ('Failed connecting to remote API server')
print ('Program ended')

@ -0,0 +1,59 @@
# Make sure to have the server side running in CoppeliaSim:
# in a child script of a CoppeliaSim scene, add following command
# to be executed just once, at simulation start:
#
# simRemoteApi.start(19999)
#
# then start simulation, and run this program.
#
# IMPORTANT: for each successful call to simxStart, there
# should be a corresponding call to simxFinish at the end!
try:
import sim
except:
print ('--------------------------------------------------------------')
print ('"sim.py" could not be imported. This means very probably that')
print ('either "sim.py" or the remoteApi library could not be found.')
print ('Make sure both are in the same folder as this file,')
print ('or appropriately adjust the file "sim.py"')
print ('--------------------------------------------------------------')
print ('')
import time
print ('Program started')
sim.simxFinish(-1) # just in case, close all opened connections
clientID=sim.simxStart('127.0.0.1',19999,True,True,5000,5) # Connect to CoppeliaSim
if clientID!=-1:
print ('Connected to remote API server')
# Now try to retrieve data in a blocking fashion (i.e. a service call):
res,objs=sim.simxGetObjects(clientID,sim.sim_handle_all,sim.simx_opmode_blocking)
if res==sim.simx_return_ok:
print ('Number of objects in the scene: ',len(objs))
else:
print ('Remote API function call returned with error code: ',res)
time.sleep(2)
# Now retrieve streaming data (i.e. in a non-blocking fashion):
startTime=time.time()
sim.simxGetIntegerParameter(clientID,sim.sim_intparam_mouse_x,sim.simx_opmode_streaming) # Initialize streaming
while time.time()-startTime < 5:
returnCode,data=sim.simxGetIntegerParameter(clientID,sim.sim_intparam_mouse_x,sim.simx_opmode_buffer) # Try to retrieve the streamed data
if returnCode==sim.simx_return_ok: # After initialization of streaming, it will take a few ms before the first value arrives, so check the return code
print ('Mouse position x: ',data) # Mouse position x is actualized when the cursor is over CoppeliaSim's window
time.sleep(0.005)
# Now send some data to CoppeliaSim in a non-blocking fashion:
sim.simxAddStatusbarMessage(clientID,'Hello CoppeliaSim!',sim.simx_opmode_oneshot)
# Before closing the connection to CoppeliaSim, make sure that the last command sent out had time to arrive. You can guarantee this with (for example):
sim.simxGetPingTime(clientID)
# Now close the connection to CoppeliaSim:
sim.simxFinish(clientID)
else:
print ('Failed connecting to remote API server')
print ('Program ended')

@ -0,0 +1,286 @@
function sysCall_threadmain()
-- Get some handles first:
-- local leftMotor=sim.getObjectHandle("remoteApiControlledBubbleRobLeftMotor") -- Handle of the left motor
-- local rightMotor=sim.getObjectHandle("remoteApiControlledBubbleRobRightMotor") -- Handle of the right motor
-- local noseSensor=sim.getObjectHandle("remoteApiControlledBubbleRobSensingNose") -- Handle of the proximity sensor
-- Choose a port that is probably not used (try to always use a similar code):
--[[
sim.setThreadAutomaticSwitch(false)
local portNb=sim.getInt32Parameter(sim.intparam_server_port_next)
local portStart=sim.getInt32Parameter(sim.intparam_server_port_start)
local portRange=sim.getInt32Parameter(sim.intparam_server_port_range)
local newPortNb=portNb+1
if (newPortNb>=portStart+portRange) then
newPortNb=portStart
end
sim.setInt32Parameter(sim.intparam_server_port_next,newPortNb)
sim.setThreadAutomaticSwitch(true)
--]]
-- Check what OS we are using:
platf=sim.getInt32Parameter(sim.intparam_platform)
if (platf==0) then
pluginFile='simExtRemoteApi.dll'
end
if (platf==1) then
pluginFile='libsimExtRemoteApi.dylib'
end
if (platf==2) then
pluginFile='libsimExtRemoteApi.so'
end
-- Check if the required legacy remote Api plugin is there:
moduleName=0
moduleVersion=0
index=0
pluginNotFound=true
while moduleName do
moduleName,moduleVersion=sim.getModuleName(index)
if (moduleName=='RemoteApi') then
pluginNotFound=false
end
index=index+1
end
if (pluginNotFound) then
-- Plugin was not found
sim.displayDialog('Error',"Remote Api plugin was not found. ('"..pluginFile.."')&&nSimulation will not run properly",sim.dlgstyle_ok,true,nil,{0.8,0,0,0,0,0},{0.5,0,0,1,1,1})
else
-- Ok, we found the plugin.
-- We first start the remote Api server service (this requires the simExtRemoteApi plugin):
-- simRemoteApi.start(portNb) -- this server function will automatically close again at simulation end
simRemoteApi.start(19999)
-- Now we start the client application:
--result=sim.launchExecutable('bubbleRobClient_remoteApi',portNb.." "..leftMotor.." "..rightMotor.." "..noseSensor,0) -- set the last argument to 1 to see the console of the launched client
-- if (result==-1) then
-- The executable could not be launched!
-- sim.displayDialog('Error',"'bubbleRobClient_remoteApi' could not be launched. &&nSimulation will not run properly",sim.dlgstyle_ok,true,nil,{0.8,0,0,0,0,0},{0.5,0,0,1,1,1})
-- end
end
-- This thread ends here. The bubbleRob will however still be controlled by
-- the client application via the legacy remote Api mechanism!
end
function sysCall_cleanup()
-- Put some clean-up code here
end
-- See the user manual or the available code snippets for additional callback functions and details
function getRobotHandle(inInts,inFloats,inStrings,inBuffer)
-- inInts, inFloats and inStrings are tables
-- inBuffer is a string
robotHandle=sim.getObjectAssociatedWithScript(sim.handle_self)
-- Perform any type of operation here.
-- Always return 3 tables and a string, e.g.:
return {},{},{},robotHandle
end
-- This is an extremely simple control script for the motorbike. It is meant as a SIMPLE example!
getRobotPos=function(inInts,inFloats,inStrings,inBuffer)
robotHandle=sim.getObjectAssociatedWithScript(sim.handle_self)
position=sim.getObjectPosition(robotHandle,-1)
return {},position,{},''
end
function setRobotPos(inInts,inFloats,inStrings,inBuffer)
robotHandle=sim.getObjectAssociatedWithScript(sim.handle_self)
position=sim.getObjectPosition(robotHandle,-1)
return {},position,{},''
end
--[[
robotHandle=sim.getObjectAssociatedWithScript(sim.handle_self)
-- Retrieve some object handles:
motor=sim.getObjectHandle('Motorbike_motor')
steering=sim.getObjectHandle('Motorbike_steeringMotor')
motorbike=sim.getObjectHandle('Motorbike')
path=sim.getObjectHandle('Motorbike_path')
pathFollower=sim.getObjectHandle('Motorbike_pathFollower')
pathFollowerTarget=sim.getObjectHandle('Motorbike_pathFollowerTarget')
-- Make the path object orphan (because at the beginning of the simulation it is still built on the motorbike model):
sim.setObjectParent(path,-1,true)
-- Set a fixed velocity:
velocity = 30
cStep = 5
step = 0.00
deviation = 0.0
t = 0
CInfo = {}
for i = 1,2,1 do
CInfo[i] = 0
end
oldPos = {}
nowLA = {}
basicPos = {}
for i = 1,3,1 do
oldPos[i] = 0
nowLA[2*i-1] = 0.0
nowLA[2*i] = 0.0
basicPos[1] = {5.35,14.65,0.7575,-0.020503, -1.486533, -1.590551}
basicPos[2] = {-16.175,-1.875,0.7575,1.485270,-0.178061,-0.010568}
basicPos[3] = {-9.45,-16.3,0.7575,0.819122, 1.447427, 0.747879}
basicPos[4] = {8.975,-12.7,0.7575,-1.451466,0.786589,3.057870}
end
inclination = 0
counter = 0
------------------------------------------
-- Check if the required ROS plugin is there:
moduleName=0
moduleVersion=0
index=0
RosInterface=false
while moduleName do
moduleName,moduleVersion=sim.getModuleName(index)
if (moduleName=='RosInterface') then
RosInterface=true
end
index=index+1
end
if (RosInterface) then
sim.addStatusbarMessage('Ros Connected')
-- Prepare the sensor publisher and the motor speed subscribers:
-- Publisher
The_Pos = simExtRosInterface_advertise('/The_P', 'std_msgs/Float32MultiArray')
The_Vec = simExtRosInterface_advertise('/The_V', 'std_msgs/Float32MultiArray')
The_Inf = simExtRosInterface_advertise('/The_I', 'std_msgs/Float32MultiArray')
The_Loc = simExtRosInterface_advertise('/The_L', 'std_msgs/Float32MultiArray')
The_Time = simExtRosInterface_advertise('/The_T', 'std_msgs/Float32MultiArray')
--Subscriber
Controller = simExtRosInterface_subscribe('/Ctrl_I','std_msgs/Float32MultiArray','setControlInfo')
ResetRobot=simExtRosInterface_subscribe('/resetRobot','std_msgs/UInt32','resetRobot_cb')
end
end
--]]
-- do some initialization here
robotHandle=sim.getObjectAssociatedWithScript(sim.handle_self)
-- Reset robot subscriber callback
allModelObjects=sim.getObjectsInTree(robotHandle)
sim.setThreadAutomaticSwitch(false)
for i=1,#allModelObjects,1 do
sim.resetDynamicObject(allModelObjects[i]) -- reset all objects in the model
end
--basicEle = sim.getObjectOrientation(robotHandle, -1)
--basicEle = sim.getObjectQuaternion(robotHandle, -1)
--sim.addStatusbarMessage(string.format(" -> %f --> msg: %d",basicEle[1],msg.data))
--sim.addStatusbarMessage(string.format("--> %f --> msg: %d",basicEle[2],msg.data))
--sim.addStatusbarMessage(string.format("--> %f --> msg: %d",basicEle[3],msg.data))
--sim.addStatusbarMessage(string.format("--> %f",basicEle[4]))
--sim.addStatusbarMessage(string.format("--> Start Statement: %d", msg.data))
oldPos = {}
nowLA = {}
basicPos = {}
for i = 1,3,1 do
oldPos[i] = 0
nowLA[2*i-1] = 0.0
nowLA[2*i] = 0.0
basicPos[1] = {5.35,14.65,0.7575,-0.020503, -1.486533, -1.590551}
basicPos[2] = {-16.175,-1.875,0.7575,1.485270,-0.178061,-0.010568}
basicPos[3] = {-9.45,-16.3,0.7575,0.819122, 1.447427, 0.747879}
basicPos[4] = {8.975,-12.7,0.7575,-1.451466,0.786589,3.057870}
end
basicLoc = {}
basicAng = {}
nowState = msg.data
for i = 1,3,1 do
basicLoc[i] = basicPos[nowState][i]
basicAng[i] = basicPos[nowState][i+3]
end
sim.setObjectPosition(robotHandle,-1,basicLoc)
sim.setObjectOrientation(robotHandle,-1,basicAng)
sim.setThreadAutomaticSwitch(true)
function sysCall_threadmain()
-- Check if the required plugin is there:
moduleName=0
moduleVersion=0
index=0
bubbleRobModuleNotFound=true
while moduleName do
moduleName,moduleVersion=sim.getModuleName(index)
if (moduleName=='BubbleRob') then
bubbleRobModuleNotFound=false
end
index=index+1
end
if (bubbleRobModuleNotFound) then
sim.displayDialog('Error','BubbleRob plugin was not found. (v_repExtBubbleRob.dll)&&nSimulation will not run properly',sim.dlgstyle_ok,true,nil,{0.8,0,0,0,0,0},{0.5,0,0,1,1,1})
else
local jointHandles={sim.getObjectHandle('leftMotor'),sim.getObjectHandle('rightMotor')}
local sensorHandle=sim.getObjectHandle('sensingNose')
local robHandle=simBubble.create(jointHandles,sensorHandle,{0.5,0.25})
if robHandle>=0 then
simBubble.start(robHandle,20) -- control happens here
simBubble.stop(robHandle)
simBubble.destroy(robHandle)
end
end
end
function sysCall_init()
movingObjects={'bubbleRob'}
pos={}
orient={}
for k, v in pairs(movingObjects) do
h=sim.getObjectHandle(v)
movingObjects[k]=h
pos[h]=sim.getObjectPosition(h,-1)
orient[h]=sim.getObjectOrientation(h,-1)
end
posBase={}
h=sim.getObjectHandle('bubbleRob')
posBase=sim.getObjectPosition(h,-1)
end
function reset()
for k, v in pairs(movingObjects) do
sim.setObjectPosition(v,-1,pos[v])
sim.setObjectOrientation(v,-1,orient[v])
sim.resetDynamicObject(v)
end
end

@ -0,0 +1,144 @@
# Make sure to have the server side running in CoppeliaSim:
# in a child script of a CoppeliaSim scene, add following command
# to be executed just once, at simulation start:
#
# simRemoteApi.start(19999)
#
# then start simulation, and run this program.
#
# IMPORTANT: for each successful call to simxStart, there
# should be a corresponding call to simxFinish at the end!
try:
import sim
from sim import *
except:
print ('--------------------------------------------------------------')
print ('"sim.py" could not be imported. This means very probably that')
print ('either "sim.py" or the remoteApi library could not be found.')
print ('Make sure both are in the same folder as this file,')
print ('or appropriately adjust the file "sim.py"')
print ('--------------------------------------------------------------')
print ('')
import time
print('Program started')
sim.simxFinish(-1) # just in case, close all opened connections
clientID=sim.simxStart('127.0.0.1',19999,True,True,5000,5) # Connect to CoppeliaSim
if clientID!=-1:
print ('Connected to remote API server')
# Now try to retrieve data in a blocking fashion (i.e. a service call):
res,objs=sim.simxGetObjects(clientID,sim.sim_handle_all,sim.simx_opmode_blocking)
if res==sim.simx_return_ok:
print ('Number of objects in the scene: ',len(objs))
else:
print ('Remote API function call returned with error code: ',res)
# time.sleep(2)
# # Now retrieve streaming data (i.e. in a non-blocking fashion):
# startTime=time.time()
# sim.simxGetIntegerParameter(clientID,sim.sim_intparam_mouse_x,sim.simx_opmode_streaming) # Initialize streaming
# while time.time()-startTime < 5:
# returnCode,data=sim.simxGetIntegerParameter(clientID,sim.sim_intparam_mouse_x,sim.simx_opmode_buffer) # Try to retrieve the streamed data
# if returnCode==sim.simx_return_ok: # After initialization of streaming, it will take a few ms before the first value arrives, so check the return code
# print ('Mouse position x: ',data) # Mouse position x is actualized when the cursor is over CoppeliaSim's window
# time.sleep(0.005)
# Now send some data to CoppeliaSim in a non-blocking fashion:
sim.simxAddStatusbarMessage(clientID,'Hello CoppeliaSim!',sim.simx_opmode_oneshot)
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'bubbleRob',sim.sim_scripttype_childscript,
'getRobotPos',[],[],[],'',sim.simx_opmode_blocking)
if res==sim.simx_return_ok:
print (retInts)
print (retFloats)
print (retStrings)
print (retBuffer)
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'bubbleRob',sim.sim_scripttype_childscript,
'setRobotPos',[],[0,-2,0.12,0,0,0],[],'',sim.simx_opmode_blocking)
if res==sim.simx_return_ok:
print (retInts)
print (retFloats)
print (retStrings)
print (retBuffer)
res,retInts,retFloats,retStrings,retBuffer=sim.simxCallScriptFunction(clientID,'bubbleRob',sim.sim_scripttype_childscript,
'getRobotPos',[],[],[],'',sim.simx_opmode_blocking)
if res==sim.simx_return_ok:
print (retInts)
print (retFloats)
print (retStrings)
print (retBuffer)
# Retrieve some handles:
res,bubbleRob=sim.simxGetObjectHandle(clientID,'bubbleRob#',sim.simx_opmode_oneshot_wait)
res,bubbleRob_leftMotor=sim.simxGetObjectHandle(clientID,'bubbleRob_leftMotor#',sim.simx_opmode_oneshot_wait)
res,bubbleRob_rightMotor=sim.simxGetObjectHandle(clientID,'bubbleRob_rightMotor#',sim.simx_opmode_oneshot_wait)
res,bubbleRob_leftWheel=sim.simxGetObjectHandle(clientID,'bubbleRob_leftWheel#',sim.simx_opmode_oneshot_wait)
res,bubbleRob_rightWheel=sim.simxGetObjectHandle(clientID,'bubbleRob_rightWheel#',sim.simx_opmode_oneshot_wait)
res,bubbleRob_sensingNose=sim.simxGetObjectHandle(clientID,'bubbleRob_sensingNose#',sim.simx_opmode_oneshot_wait)
res,bubbleRob_visionSensor=sim.simxGetObjectHandle(clientID,'bubbleRob_visionSensor#',sim.simx_opmode_oneshot_wait)
res,bubbleRob_slider=sim.simxGetObjectHandle(clientID,'bubbleRob_slider#',sim.simx_opmode_oneshot_wait)
# getResult,position=simxGetObjectPosition(clientID,bubbleRob,-1,sim.simx_opmode_streaming)
# print(position)
# getResult,position2=simxGetObjectPosition(clientID,bubbleRob_leftWheel,-1,sim.simx_opmode_buffer)
# print(position2)
# getResult,position3=simxGetObjectPosition(clientID,bubbleRob_rightWheel,-1,sim.simx_opmode_buffer)
# print(position3)
# getResult,position4=simxGetObjectPosition(clientID,bubbleRob_slider,-1,sim.simx_opmode_buffer)
# print(position4)
# getResult,angle=simxGetObjectOrientation(clientID,bubbleRob,-1,sim.simx_opmode_streaming)
# print(angle)
# getResult,angle=simxGetObjectOrientation(clientID,bubbleRob_leftWheel,-1,sim.simx_opmode_streaming)
# print(angle)
# getResult,angle=simxGetObjectOrientation(clientID,bubbleRob_rightWheel,-1,sim.simx_opmode_streaming)
# print(angle)
# getResult,angle=simxGetObjectOrientation(clientID,bubbleRob_slider,-1,sim.simx_opmode_streaming)
# print(angle)
# setResult=simxSetObjectPosition(clientID,bubbleRob,-1,[0,-2,0.12],sim.simx_opmode_oneshot)
# print(setResult)
# setResult=simxSetObjectPosition(clientID,bubbleRob_leftWheel,-1,[0.05,-1.9,0.04],sim.simx_opmode_oneshot)
# print(setResult)
# setResult=simxSetObjectPosition(clientID,bubbleRob_rightWheel,-1,[0.05,-2.1,0.04],sim.simx_opmode_oneshot)
# print(setResult)
# setResult=simxSetObjectPosition(clientID,bubbleRob_slider,-1,[-0.07,-2,0.025],sim.simx_opmode_oneshot)
# print(setResult)
# setResult=simxSetObjectOrientation(clientID,bubbleRob,-1,[0,0,90],sim.simx_opmode_oneshot)
# print(setResult)
# setResult=simxSetObjectOrientation(clientID,bubbleRob_leftWheel,-1,[-90,90,0],sim.simx_opmode_oneshot)
# print(setResult)
# setResult=simxSetObjectOrientation(clientID,bubbleRob_rightWheel,-1,[-90,90,0],sim.simx_opmode_oneshot)
# print(setResult)
# setResult=simxSetObjectOrientation(clientID,bubbleRob_slider,-1,[0,0,90],sim.simx_opmode_oneshot)
# print(setResult)
# Before closing the connection to CoppeliaSim, make sure that the last command sent out had time to arrive. You can guarantee this with (for example):
sim.simxGetPingTime(clientID)
# Now close the connection to CoppeliaSim:
sim.simxFinish(clientID)
else:
print ('Failed connecting to remote API server')
print ('Program ended')

@ -0,0 +1,517 @@
# -*- coding: utf-8 -*-
"""Code for visualizing data in sim via python.
Author: Andrew Hundt <ATHundt@gmail.com>
License: Apache v2 https://www.apache.org/licenses/LICENSE-2.0
"""
import os
import errno
import traceback
import numpy as np
import six # compatibility between python 2 + 3 = six
import matplotlib.pyplot as plt
try:
import sim as sim
except Exception as e:
print ('--------------------------------------------------------------')
print ('"sim.py" could not be imported. This means very probably that')
print ('either "sim.py" or the remoteApi library could not be found.')
print ('Make sure both are in PYTHONPATH folder relative to this file,')
print ('or appropriately adjust the file "sim.py. Also follow the"')
print ('ReadMe.txt in the sim remote API folder')
print ('--------------------------------------------------------------')
print ('')
raise e
import tensorflow as tf
from tensorflow.python.platform import flags
from tensorflow.python.platform import gfile
from tensorflow.python.ops import data_flow_ops
from ply import write_xyz_rgb_as_ply
from PIL import Image
# progress bars https://github.com/tqdm/tqdm
# import tqdm without enforcing it as a dependency
try:
from tqdm import tqdm
except ImportError:
def tqdm(*args, **kwargs):
if args:
return args[0]
return kwargs.get('iterable', None)
from depth_image_encoding import ClipFloatValues
from depth_image_encoding import FloatArrayToRgbImage
from depth_image_encoding import FloatArrayToRawRGB
from skimage.transform import resize
from skimage import img_as_ubyte
from skimage import img_as_uint
from skimage.color import grey2rgb
try:
import eigen # https://github.com/jrl-umi3218/Eigen3ToPython
import sva # https://github.com/jrl-umi3218/SpaceVecAlg
except ImportError:
print('eigen and sva python modules are not available. To install run the script at:'
'https://github.com/ahundt/robotics_setup/blob/master/robotics_tasks.sh'
'or follow the instructions at https://github.com/jrl-umi3218/Eigen3ToPython'
'and https://github.com/jrl-umi3218/SpaceVecAlg. '
'When you build the modules make sure python bindings are enabled.')
tf.flags.DEFINE_string('csimVisualizeDepthFormat', 'csim_depth_encoded_rgb',
""" Controls how Depth images are displayed. Options are:
None: Do not modify the data and display it as-is for rgb input data (not working properly for float depth).
'depth_rgb': convert a floating point depth image to a straight 0-255 encoding of depths less than 3m
'depth_encoded_rgb': convert a floating point depth image to the rgb encoding used by
the google brain robot data grasp dataset's raw png depth image encoding,
see https://sites.google.com/site/brainrobotdata/home/depth-image-encoding.
'sim': add a sim prefix to any of the above commands to
rotate image by 180 degrees, flip left over right, then invert the color channels
after the initial conversion step.
This is due to a problem where CoppeliaSim seems to display images differently.
Examples include 'csim_depth_rgb' and 'csim_depth_encoded_rgb',
see http://forum.coppeliarobotics.com/viewtopic.php?f=9&t=737&p=27805#p27805.
""")
tf.flags.DEFINE_string('csimVisualizeRGBFormat', 'csim_rgb',
""" Controls how images are displayed. Options are:
None: Do not modify the data and display it as-is for rgb input data (not working properly for float depth).
'depth_rgb': convert a floating point depth image to a straight 0-255 encoding of depths less than 3m
'depth_encoded_rgb': convert a floating point depth image to the rgb encoding used by
the google brain robot data grasp dataset's raw png depth image encoding,
see https://sites.google.com/site/brainrobotdata/home/depth-image-encoding.
'sim': add a sim prefix to any of the above commands to
rotate image by 180 degrees, flip left over right, then invert the color channels
after the initial conversion step.
This is due to a problem where CoppeliaSim seems to display images differently.
Examples include 'csim_depth_rgb' and 'csim_depth_encoded_rgb',
see http://forum.coppeliarobotics.com/viewtopic.php?f=9&t=737&p=27805#p27805.
""")
# the following line is needed for tf versions before 1.5
# flags.FLAGS._parse_flags()
FLAGS = flags.FLAGS
def depth_image_to_point_cloud(depth, intrinsics_matrix, dtype=np.float32, verbose=0):
"""Depth images become an XYZ point cloud in the camera frame with shape (depth.shape[0], depth.shape[1], 3).
Transform a depth image into a point cloud in the camera frame with one point for each
pixel in the image, using the camera transform for a camera
centred at cx, cy with field of view fx, fy.
Based on:
https://github.com/tensorflow/models/blob/master/research/cognitive_mapping_and_planning/src/depth_utils.py
https://codereview.stackexchange.com/a/84990/10101
also see grasp_geometry_tf.depth_image_to_point_cloud().
# Arguments
depth: is a 2-D ndarray with shape (rows, cols) containing
32bit floating point depths in meters. The result is a 3-D array with
shape (rows, cols, 3). Pixels with invalid depth in the input have
NaN or 0 for the z-coordinate in the result.
intrinsics_matrix: 3x3 matrix for projecting depth values to z values
in the point cloud frame. http://ksimek.github.io/2013/08/13/intrinsic/
In this case x0, y0 are at index [2, 0] and [2, 1], respectively.
transform: 4x4 Rt matrix for rotating and translating the point cloud
"""
fy = intrinsics_matrix[1, 1]
fx = intrinsics_matrix[0, 0]
# center of image y coordinate
center_y = intrinsics_matrix[2, 1]
# center of image x coordinate
center_x = intrinsics_matrix[2, 0]
depth = np.squeeze(depth)
y_range, x_range = depth.shape
y, x = np.meshgrid(np.arange(y_range),
np.arange(x_range),
indexing='ij')
assert y.size == x.size and y.size == depth.size
x = x.flatten()
y = y.flatten()
depth = depth.flatten()
X = (x - center_x) * depth / fx
Y = (y - center_y) * depth / fy
assert X.size == Y.size and X.size == depth.size
assert X.shape == Y.shape and X.shape == depth.shape
if verbose > 0:
print('X np: ', X.shape)
print('Y np: ', Y.shape)
print('depth np: ', depth.shape)
XYZ = np.column_stack([X, Y, depth])
assert XYZ.shape == (y_range * x_range, 3)
if verbose > 0:
print('XYZ pre reshape np: ', XYZ.shape)
XYZ = XYZ.reshape((y_range, x_range, 3))
return XYZ.astype(dtype)
def csimPrint(client_id, message):
"""Print a message in both the python command line and on the CoppeliaSim Statusbar.
The Statusbar is the white command line output on the bottom of the CoppeliaSim GUI window.
"""
sim.simxAddStatusbarMessage(client_id, message, sim.simx_opmode_oneshot)
print(message)
def create_dummy(client_id, display_name, transform=None, parent_handle=-1, debug=FLAGS.csimDebugMode, operation_mode=sim.simx_opmode_blocking):
"""Create a dummy object in the simulation
# Arguments
transform_display_name: name string to use for the object in the sim scene
transform: 3 cartesian (x, y, z) and 4 quaternion (x, y, z, w) elements, same as sim
parent_handle: -1 is the world frame, any other int should be a sim object handle
"""
if transform is None:
transform = np.array([0., 0., 0., 0., 0., 0., 1.])
# 2. Now create a dummy object at coordinate 0.1,0.2,0.3 with name 'MyDummyName':
empty_buffer = bytearray()
res, ret_ints, ret_floats, ret_strings, ret_buffer = sim.simxCallScriptFunction(
client_id,
'remoteApiCommandServer',
sim.sim_scripttype_childscript,
'createDummy_function',
[parent_handle],
transform,
[display_name],
empty_buffer,
operation_mode)
if res == sim.simx_return_ok:
# display the reply from CoppeliaSim (in this case, the handle of the created dummy)
if debug is not None and 'print_transform' in debug:
print ('Dummy name:', display_name, ' handle: ', ret_ints[0], ' transform: ', transform)
else:
print('create_dummy remote function call failed.')
print(''.join(traceback.format_stack()))
return -1
return ret_ints[0]
def setPose(client_id, display_name, transform=None, parent_handle=-1):
"""Set the pose of an object in the simulation
# Arguments
transform_display_name: name string to use for the object in the sim scene
transform: 3 cartesian (x, y, z) and 4 quaternion (x, y, z, w) elements, same as sim
parent_handle: -1 is the world frame, any other int should be a sim object handle
"""
if transform is None:
transform = np.array([0., 0., 0., 0., 0., 0., 1.])
# 2. Now create a dummy object at coordinate 0.1,0.2,0.3 with name 'MyDummyName':
empty_buffer = bytearray()
res, ret_ints, ret_floats, ret_strings, ret_buffer = sim.simxCallScriptFunction(
client_id,
'remoteApiCommandServer',
sim.sim_scripttype_childscript,
'createDummy_function',
[parent_handle],
transform,
[display_name],
empty_buffer,
sim.simx_opmode_blocking)
if res == sim.simx_return_ok:
# display the reply from CoppeliaSim (in this case, the handle of the created dummy)
print ('SetPose object name:', display_name, ' handle: ', ret_ints[0], ' transform: ', transform)
else:
print('setPose remote function call failed.')
print(''.join(traceback.format_stack()))
return -1
return ret_ints[0]
def set_vision_sensor_image(client_id, display_name, image, convert=None, scale_factor=256000.0, operation_mode=sim.simx_opmode_oneshot_wait):
"""Display vision sensor image data in a CoppeliaSim simulation.
[CoppeliaSim Vision Sensors](http://www.coppeliarobotics.com/helpFiles/en/visionSensors.htm)
[simSetVisionSensorImage](http://www.coppeliarobotics.com/helpFiles/en/apiFunctions.htm#simSetVisionSensorImage)
# Arguments
display_name: the string display name of the sensor object in the CoppeliaSim scene
image: an rgb char array containing an image
convert: Controls how images are displayed. Options are:
None: Do not modify the data and display it as-is for rgb input data (not working properly for float depth).
'depth_rgb': convert a floating point depth image to a straight 0-255 encoding of depths less than 3m
'depth_encoded_rgb': convert a floating point depth image to the rgb encoding used by
the google brain robot data grasp dataset's raw png depth image encoding,
see https://sites.google.com/site/brainrobotdata/home/depth-image-encoding.
'sim': add a sim prefix to any of the above commands to
rotate image by 180 degrees, flip left over right, then invert the color channels
after the initial conversion step.
This is due to a problem where CoppeliaSim seems to display images differently.
Examples include 'csim_depth_rgb' and 'csim_depth_encoded_rgb',
see http://www.forum.coppeliarobotics.com/viewtopic.php?f=9&t=737&p=27805#p27805.
"""
strings = [display_name]
parent_handle = -1
# TODO(ahundt) support is_greyscale True again
is_greyscale = 0
csim_conversion = False
if convert is not None:
csim_conversion = 'sim' in convert
if 'depth_encoded_rgb' in convert:
image = np.array(FloatArrayToRgbImage(image, scale_factor=scale_factor, drop_blue=False), dtype=np.uint8)
elif 'depth_rgb' in convert:
image = img_as_uint(image)
elif not csim_conversion:
raise ValueError('set_vision_sensor_image() convert parameter must be one of `depth_encoded_rgb`, `depth_rgb`, or None'
'with the optional addition of the word `sim` to rotate 180, flip left right, then invert colors.')
if csim_conversion:
# rotate 180 degrees, flip left over right, then invert the colors
image = np.array(256 - np.fliplr(np.rot90(image, 2)), dtype=np.uint8)
if np.issubdtype(image.dtype, np.integer):
is_float = 0
floats = []
color_buffer = bytearray(image.flatten().tobytes())
color_size = image.size
num_floats = 0
else:
is_float = 1
floats = [image]
color_buffer = bytearray()
num_floats = image.size
color_size = 0
cloud_handle = -1
res, ret_ints, ret_floats, ret_strings, ret_buffer = sim.simxCallScriptFunction(
client_id,
'remoteApiCommandServer',
sim.sim_scripttype_childscript,
'setVisionSensorImage_function',
[parent_handle, num_floats, is_greyscale, color_size], # int params
np.append(floats, []), # float params
strings, # string params
# byte buffer params
color_buffer,
operation_mode)
if res == sim.simx_return_ok:
print ('point cloud handle: ', ret_ints[0]) # display the reply from CoppeliaSim (in this case, the handle of the created dummy)
# set the transform for the point cloud
return ret_ints[0]
else:
print('insertPointCloud_function remote function call failed.')
print(''.join(traceback.format_stack()))
return res
def create_point_cloud(client_id, display_name, transform=None, point_cloud=None, depth_image=None, color_image=None,
camera_intrinsics_matrix=None, parent_handle=-1, clear=True,
max_voxel_size=0.01, max_point_count_per_voxel=10, point_size=10, options=8,
rgb_sensor_display_name=None, depth_sensor_display_name=None, convert_depth=FLAGS.csimVisualizeDepthFormat,
convert_rgb=FLAGS.csimVisualizeRGBFormat, save_ply_path=None, rgb_display_mode='vision_sensor'):
"""Create a point cloud object in the simulation, plus optionally render the depth and rgb images.
# Arguments
display_name: name string to use for the object in the sim scene
depth_image: A depth image of size [width, height, 3]
transform: [x, y, z, qw, qx, qy, qz] with 3 cartesian (x, y, z) and 4 quaternion (qx, qy, qz, qw) elements, same as sim
This transform is from the parent handle to the point cloud base
parent_handle: -1 is the world frame, any other int should be a sim object handle
clear: clear the point cloud if it already exists with the provided display name
maxVoxelSize: the maximum size of the octree voxels containing points
maxPtCntPerVoxel: the maximum number of points allowed in a same octree voxel
options: bit-coded:
bit0 set (1): points have random colors
bit1 set (2): show octree structure
bit2 set (4): reserved. keep unset
bit3 set (8): do not use an octree structure. When enabled, point cloud operations are limited, and point clouds will not be collidable, measurable or detectable anymore, but adding points will be much faster
bit4 set (16): color is emissive
pointSize: the size of the points, in pixels
reserved: reserved for future extensions. Set to NULL
save_ply_path: save out a ply file with the point cloud data
point_cloud: optional XYZ point cloud of size [width, height, 3], will be generated if not provided.
convert_rgb: Controls how images are displayed. Options are:
None: Do not modify the data and display it as-is for rgb input data (not working properly for float depth).
'depth_rgb': convert a floating point depth image to a straight 0-255 encoding of depths less than 3m
'depth_encoded_rgb': convert a floating point depth image to the rgb encoding used by
the google brain robot data grasp dataset's raw png depth image encoding,
see https://sites.google.com/site/brainrobotdata/home/depth-image-encoding.
'sim': add a sim prefix to any of the above commands to
rotate image by 180 degrees, flip left over right, then invert the color channels
after the initial conversion step.
This is due to a problem where CoppeliaSim seems to display images differently.
Examples include 'csim_depth_rgb' and 'csim_depth_encoded_rgb',
see http://www.forum.coppeliarobotics.com/viewtopic.php?f=9&t=737&p=27805#p27805.
rgb_display_mode: Options help with working around quirks in input image data's layout.
'point_cloud' to display the image when the point cloud is being generated.
'vision_sensor' to make a separate call go the vison sensor display function.
"""
if transform is None:
transform = np.array([0., 0., 0., 0., 0., 0., 1.])
if point_cloud is None:
point_cloud = depth_image_to_point_cloud(depth_image, camera_intrinsics_matrix)
point_cloud = point_cloud.reshape([point_cloud.size/3, 3])
# show the depth sensor image
if depth_sensor_display_name is not None and depth_image is not None:
# matplotlib.image.imsave(display_name + depth_sensor_display_name + '_norotfliplr.png', depth_image)
# rotate 180, flip left over right then invert the image colors for display in CoppeliaSim
# depth_image = np.fliplr(np.rot90(depth_image, 2))
# matplotlib.image.imsave(display_name + depth_sensor_display_name + '_rot90fliplr.png', depth_image)
set_vision_sensor_image(client_id, depth_sensor_display_name, depth_image, convert=convert_depth)
# show the rgb sensor image, this overwrites the rgb display
# done in insertPointCloud_function, which is buggy
if rgb_sensor_display_name is not None and color_image is not None and rgb_display_mode == 'vision_sensor':
# matplotlib.image.imsave(display_name + rgb_sensor_display_name + '_norotfliplr.png', color_image)
# rotate 180, flip left over right then invert the image colors for display in CoppeliaSim
# matplotlib.image.imsave(display_name + rgb_sensor_display_name + '_rot90fliplr.png', color_image)
set_vision_sensor_image(client_id, rgb_sensor_display_name, color_image, convert=convert_rgb)
# Save out Point cloud
if save_ply_path is not None:
write_xyz_rgb_as_ply(point_cloud, color_image, save_ply_path)
# color_buffer is initially empty
color_buffer = bytearray()
strings = [display_name]
if rgb_sensor_display_name is not None and rgb_display_mode == 'point_cloud':
strings = [display_name, rgb_sensor_display_name]
transform_entries = 7
if clear:
clear = 1
else:
clear = 0
cloud_handle = -1
# Create the point cloud if it does not exist, or retrieve the handle if it does
res, ret_ints, ret_floats, ret_strings, ret_buffer = sim.simxCallScriptFunction(
client_id,
'remoteApiCommandServer',
sim.sim_scripttype_childscript,
'createPointCloud_function',
# int params
[parent_handle, transform_entries, point_cloud.size, cloud_handle, clear, max_point_count_per_voxel, options, point_size],
# float params
[max_voxel_size],
# string params
strings,
# byte buffer params
color_buffer,
sim.simx_opmode_blocking)
setPose(client_id, display_name, transform, parent_handle)
if res == sim.simx_return_ok:
cloud_handle = ret_ints[0]
# convert the rgb values to a string
color_size = 0
if color_image is not None:
# see simInsertPointsIntoPointCloud() in sim documentation
# 3 indicates the cloud should be in the parent frame, and color is enabled
# bit 2 is 1 so each point is colored
simInsertPointsIntoPointCloudOptions = 3
# color_buffer = bytearray(np.fliplr(np.rot90(color_image, 3)).flatten().tobytes())
color_buffer = bytearray(color_image.flatten().tobytes())
color_size = color_image.size
else:
simInsertPointsIntoPointCloudOptions = 1
# Actually transfer the point cloud
res, ret_ints, ret_floats, ret_strings, ret_buffer = sim.simxCallScriptFunction(
client_id,
'remoteApiCommandServer',
sim.sim_scripttype_childscript,
'insertPointCloud_function',
[parent_handle, transform_entries, point_cloud.size, cloud_handle, color_size, simInsertPointsIntoPointCloudOptions],
np.append(point_cloud, []),
strings,
color_buffer,
sim.simx_opmode_blocking)
if res == sim.simx_return_ok:
print ('point cloud handle: ', ret_ints[0]) # display the reply from CoppeliaSim (in this case, the handle of the created dummy)
# set the transform for the point cloud
return ret_ints[0]
else:
print('insertPointCloud_function remote function call failed.')
print(''.join(traceback.format_stack()))
return res
else:
print('createPointCloud_function remote function call failed')
print(''.join(traceback.format_stack()))
return res
def drawLines(client_id, display_name, lines, parent_handle=-1, transform=None, debug=FLAGS.csimDebugMode, operation_mode=sim.simx_opmode_blocking):
"""Create a line in the simulation.
Note that there are currently some quirks with this function. Only one line is accepted,
and sometimes CoppeliaSim fails to delete the object correctly and lines will fail to draw.
In that case you need to close and restart CoppeliaSim.
# Arguments
transform_display_name: name string to use for the object in the sim scene
transform: 3 cartesian (x, y, z) and 4 quaternion (x, y, z, w) elements, same as sim
parent_handle: -1 is the world frame, any other int should be a sim object handle
lines: array of line definitions using two endpoints (x0, y0, z0, x1, y1, z1).
Multiple lines can be defined but there should be 6 entries (two points) per line.
"""
# 2. Now create a dummy object at coordinate 0.1,0.2,0.3 with name 'MyDummyName':
empty_buffer = bytearray()
res, ret_ints, ret_floats, ret_strings, ret_buffer = sim.simxCallScriptFunction(
client_id,
'remoteApiCommandServer',
sim.sim_scripttype_childscript,
'addDrawingObject_function',
[parent_handle, int(lines.size/6)],
# np.append(transform, lines),
lines,
[display_name],
empty_buffer,
operation_mode)
if res == sim.simx_return_ok:
# display the reply from CoppeliaSim (in this case, the handle of the created dummy)
if debug is not None and 'print_drawLines' in debug:
print ('drawLines name:', display_name, ' handle: ', ret_ints[0], ' transform: ', transform)
if transform is not None:
# set the transform for the point cloud
setPose(client_id, display_name, transform, parent_handle)
else:
print('drawLines remote function call failed.')
print(''.join(traceback.format_stack()))
return -1
return ret_ints[0]
def restore_cropped(cropped_image, crop_size, crop_offset, full_size):
""" Restore cropped_image to full size image with zero padding
First scale image back to crop_size, then padding
"""
cropped_image = np.squeeze(cropped_image)
restored = np.zeros((full_size[0], full_size[1]), dtype=cropped_image.dtype)
scaled_crop = resize(cropped_image, (crop_size[0], crop_size[1]))
restored[crop_offset[0]:crop_offset[0]+crop_size[0],
crop_offset[1]:crop_offset[1]+crop_size[1]] = scaled_crop
return restored

@ -0,0 +1,14 @@
git clone https://github.com/sybrenstuvel/Python-RVO2.git
cd Python-RVO2-master
# todo : install conda and create env for py3.6
conda activate autorobot
conda install numpy
python -V
pip install -r requirements.txt --user
python setup.py build
python setup.py install --user
todo:

@ -0,0 +1,161 @@
#!/usr/bin/env python2
import rospy
from std_msgs.msg import String
from std_msgs.msg import Float32MultiArray
from std_msgs.msg import MultiArrayLayout
import sys
sys.path.append ('./python')
import sim
from sim import *
import numpy as np
from utils.human import Human
from utils.robot import Robot
import logging
import argparse
import configparser
from numpy.linalg import norm
import time
class Sensor(object):
"""docstring for ."""
def __init__(self,clientID, config,robot):
self.robot = robot
self.config = config
self.clientID = clientID
self.all_actions = [0 for i in range(12)]
sim.simxStopSimulation(clientID, sim.simx_opmode_oneshot)
time.sleep(0.5)
sim.simxStartSimulation(clientID, sim.simx_opmode_oneshot)
time.sleep(0.5)
sim.simxPauseSimulation(clientID, sim.simx_opmode_oneshot)
time.sleep(0.5)
self.circle_radius = config.getfloat('sim', 'circle_radius')
self.discomfort_dist = config.getfloat('reward', 'discomfort_dist')
self.robot.set(0, -self.circle_radius, 0, self.circle_radius, 0, 0, np.pi / 2)
np.random.seed(1)
self.generate_random_human_position(human_num=5)
# get current observation
ob = [human.get_observable_state() for human in self.humans]
# collect agents' states in gym env
fullstate = self.robot.get_full_state()
reset_info = []
reset_info.extend([fullstate.px, fullstate.py])
for index, human in enumerate(ob):
# human_theta = np.arctan2(human.vy, human.vx)
reset_info.extend([human.px, human.py])
res, retInts, retFloats, retStrings, retBuffer = sim.simxCallScriptFunction(self.clientID,
'remoteApiCommandServer',
sim.sim_scripttype_childscript,
'setRobotPos', [], reset_info,
[], '',
sim.simx_opmode_blocking)
sim.simxStartSimulation(self.clientID, sim.simx_opmode_oneshot)
time.sleep(2)
rospy.init_node('talker')
self.pub = rospy.Publisher('chatter', Float32MultiArray, queue_size=2)
self.sub = rospy.Subscriber('act_cmd', Float32MultiArray, self. callback)
res, retInts, retFloats, retStrings, retBuffer = sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'setVelGetPos', [],self.all_actions, [], '',sim.simx_opmode_blocking)
rospy.loginfo(retStrings)
data = Float32MultiArray()
# retFloats = [round(i,4) for i in retFloats]
data.data = retFloats
# data.layout = MultiArrayLayout()
self.pub.publish(data)
time.sleep(0.1)
self.pub.publish(data)
time.sleep(0.1)
self.pub.publish(data)
time.sleep(0.1)
self.pub.publish(data)
rate = rospy.Rate(500)
while not rospy.is_shutdown():
# all_actions = [0 for i in range(12)]
rate.sleep()
def callback(self, data):
if (len(data.data)!=0):
rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)
actCmd = list(data.data)
self.all_actions = actCmd
# print(actCmd)
res, retInts, retFloats, retStrings, retBuffer = sim.simxCallScriptFunction(clientID,'remoteApiCommandServer',sim.sim_scripttype_childscript,'setVelGetPos', [],self.all_actions, [], '',sim.simx_opmode_blocking)
rospy.loginfo(retStrings)
data = Float32MultiArray()
# retFloats = [round(i,4) for i in retFloats]
data.data = retFloats
# data.layout = MultiArrayLayout()
self.pub.publish(data)
def generate_random_human_position(self, human_num):
self.humans = []
for i in range(human_num):
self.humans.append(self.generate_circle_crossing_human())
def generate_circle_crossing_human(self):
human = Human(self.config, 'humans')
while True:
angle = np.random.random() * np.pi * 2
# add some noise to simulate all the possible cases robot could meet with human
px_noise = (np.random.random() - 0.5) * human.v_pref
py_noise = (np.random.random() - 0.5) * human.v_pref
px = self.circle_radius * np.cos(angle) + px_noise
py = self.circle_radius * np.sin(angle) + py_noise
collide = False
for agent in [self.robot] + self.humans:
min_dist = human.radius + agent.radius + self.discomfort_dist
if norm((px - agent.px, py - agent.py)) < min_dist or \
norm((px - agent.gx, py - agent.gy)) < min_dist:
collide = True
break
if not collide:
break
human.set(px, py, -px, -py, 0, 0, 0)
return human
if __name__ == '__main__':
print('Vrep Sim Program started 2')
# configure environment
parser = argparse.ArgumentParser('Parse configuration file')
parser.add_argument('--env_config', type=str, default='env.config')
args = parser.parse_args()
env_config = configparser.RawConfigParser()
env_config.read(args.env_config)
robot = Robot(env_config, 'robot')
sim.simxFinish(-1) # just in case, close all opened connections
clientID = sim.simxStart('127.0.0.1', 19997, True, True, 5000, 5) # Connect to CoppeliaSim
if clientID != -1:
print('Connected to remote API server 2')
# Now try to retrieve data in a blocking fashion (i.e. a service call):
res, objs = sim.simxGetObjects(clientID, sim.sim_handle_all, sim.simx_opmode_blocking)
if res == sim.simx_return_ok:
print('Number of objects in the scene 2: ', len(objs))
else:
print('Remote API function call returned with error code: ', res)
# time.sleep(2)
else:
print('Failed connecting to remote API server')
pass
try:
Sensor(clientID, env_config, robot)
except rospy.ROSInterruptException:
pass

@ -0,0 +1,4 @@
from collections import namedtuple
ActionXY = namedtuple('ActionXY', ['vx', 'vy'])
ActionRot = namedtuple('ActionRot', ['v', 'r'])

@ -0,0 +1,140 @@
import numpy as np
from numpy.linalg import norm
import abc
import logging
import sys
from policy.policy_factory import policy_factory
from action import ActionXY, ActionRot
from state import ObservableState, FullState
class Agent(object):
def __init__(self, config, section):
"""
Base class for robot and human. Have the physical attributes of an agent.
"""
self.visible = config.getboolean(section, 'visible')
self.v_pref = config.getfloat(section, 'v_pref')
self.radius = config.getfloat(section, 'radius')
self.policy = policy_factory[config.get(section, 'policy')]()
self.sensor = config.get(section, 'sensor')
self.kinematics = self.policy.kinematics if self.policy is not None else None
self.px = None
self.py = None
self.gx = None
self.gy = None
self.vx = None
self.vy = None
self.theta = None
self.time_step = None
def print_info(self):
logging.info('Agent is {} and has {} kinematic constraint'.format(
'visible' if self.visible else 'invisible', self.kinematics))
def set_policy(self, policy):
self.policy = policy
self.kinematics = policy.kinematics
def sample_random_attributes(self):
"""
Sample agent radius and v_pref attribute from certain distribution
:return:
"""
self.v_pref = np.random.uniform(0.5, 1.5)
self.radius = np.random.uniform(0.3, 0.5)
def set(self, px, py, gx, gy, vx, vy, theta, radius=None, v_pref=None):
self.px = px
self.py = py
self.gx = gx
self.gy = gy
self.vx = vx
self.vy = vy
self.theta = theta
if radius is not None:
self.radius = radius
if v_pref is not None:
self.v_pref = v_pref
def get_observable_state(self):
return ObservableState(self.px, self.py, self.vx, self.vy, self.radius)
def get_next_observable_state(self, action):
self.check_validity(action)
pos = self.compute_position(action, self.time_step)
next_px, next_py = pos
if self.kinematics == 'holonomic':
next_vx = action.vx
next_vy = action.vy
else:
next_theta = self.theta + action.r
next_vx = action.v * np.cos(next_theta)
next_vy = action.v * np.sin(next_theta)
return ObservableState(next_px, next_py, next_vx, next_vy, self.radius)
def get_full_state(self):
return FullState(self.px, self.py, self.vx, self.vy, self.radius, self.gx, self.gy, self.v_pref, self.theta)
def get_position(self):
return self.px, self.py
def set_position(self, position):
self.px = position[0]
self.py = position[1]
def get_goal_position(self):
return self.gx, self.gy
def get_velocity(self):
return self.vx, self.vy
def set_velocity(self, velocity):
self.vx = velocity[0]
self.vy = velocity[1]
self.theta = np.arctan2(velocity[1], velocity[0])
@abc.abstractmethod
def act(self, ob):
"""
Compute state using received observation and pass it to policy
"""
return
def check_validity(self, action):
if self.kinematics == 'holonomic':
assert isinstance(action, ActionXY)
else:
assert isinstance(action, ActionRot)
def compute_position(self, action, delta_t):
self.check_validity(action)
if self.kinematics == 'holonomic':
px = self.px + action.vx * delta_t
py = self.py + action.vy * delta_t
else:
theta = self.theta + action.r
px = self.px + np.cos(theta) * action.v * delta_t
py = self.py + np.sin(theta) * action.v * delta_t
return px, py
def step(self, action):
"""
Perform an action and update the state
"""
self.check_validity(action)
pos = self.compute_position(action, self.time_step)
self.px, self.py = pos
if self.kinematics == 'holonomic':
self.vx = action.vx
self.vy = action.vy
else:
self.theta = (self.theta + action.r) % (2 * np.pi)
self.vx = action.v * np.cos(self.theta)
self.vy = action.v * np.sin(self.theta)
def reached_destination(self):
return norm(np.array(self.get_position()) - np.array(self.get_goal_position())) < self.radius

@ -0,0 +1,17 @@
from agent import Agent
from state import JointState
class Human(Agent):
def __init__(self, config, section):
super(Human, self).__init__(config, section)
def act(self, ob):
"""
The state for human is its full state and all other agents' observable states
:param ob:
:return:
"""
state = JointState(self.get_full_state(), ob)
action = self.policy.predict(state)
return action

@ -0,0 +1,14 @@
from agent import Agent
from state import JointState
class Robot(Agent):
def __init__(self, config, section):
super(Robot, self).__init__(config, section)
def act(self, ob):
if self.policy is None:
raise AttributeError('Policy attribute has to be set!')
state = JointState(self.get_full_state(), ob)
action = self.policy.predict(state)
return action

@ -0,0 +1,50 @@
class FullState(object):
def __init__(self, px, py, vx, vy, radius, gx, gy, v_pref, theta):
self.px = px
self.py = py
self.vx = vx
self.vy = vy
self.radius = radius
self.gx = gx
self.gy = gy
self.v_pref = v_pref
self.theta = theta
self.position = (self.px, self.py)
self.goal_position = (self.gx, self.gy)
self.velocity = (self.vx, self.vy)
def __add__(self, other):
return other + (self.px, self.py, self.vx, self.vy, self.radius, self.gx, self.gy, self.v_pref, self.theta)
def __str__(self):
return ' '.join([str(x) for x in [self.px, self.py, self.vx, self.vy, self.radius, self.gx, self.gy,
self.v_pref, self.theta]])
class ObservableState(object):
def __init__(self, px, py, vx, vy, radius):
self.px = px
self.py = py
self.vx = vx
self.vy = vy
self.radius = radius
self.position = (self.px, self.py)
self.velocity = (self.vx, self.vy)
def __add__(self, other):
return other + (self.px, self.py, self.vx, self.vy, self.radius)
def __str__(self):
return ' '.join([str(x) for x in [self.px, self.py, self.vx, self.vy, self.radius]])
class JointState(object):
def __init__(self, self_state, human_states):
assert isinstance(self_state, FullState)
for human_state in human_states:
assert isinstance(human_state, ObservableState)
self.self_state = self_state
self.human_states = human_states

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

@ -0,0 +1,53 @@
The commons-codec team is pleased to announce the Codec 1.3 release!
http://jakarta.apache.org/commons/codec/
The codec package contains simple encoder and decoders for various formats
such as Base64 and Hexadecimal. In addition to these widely used encoders and
decoders, the codec package also maintains a collection of phonetic encoding
utilities.
Changes in this version include:
New Features:
o BinaryCodec: Encodes and decodes binary to and from Strings of 0s and 1s.
Issue: 27813. Thanks to Alex Karasulu.
o QuotedPrintableCodec: Codec for RFC 1521 MIME (Multipurpose Internet Mail
Extensions) Part One. Rules #3, #4, and #5 of the quoted-printable spec are
not implemented yet. See also issue 27789. Issue: 26617. Thanks to Oleg
Kalnichevski.
o BCodec: Identical to the Base64 encoding defined by RFC 1521 and allows a
character set to be specified. Issue: 26617. Thanks to Oleg Kalnichevski.
o QCodec: Similar to the Quoted-Printable content-transfer-encoding defined
in RFC 1521 and designed to allow text containing mostly ASCII characters
to be decipherable on an ASCII terminal without decoding. Issue: 26617.
Thanks to Oleg Kalnichevski.
o Soundex: Implemented the DIFFERENCE algorithm. Issue: 25243. Thanks to
Matthew Inger.
o RefinedSoundex: Implemented the DIFFERENCE algorithm. Issue: 25243. Thanks
to Matthew Inger.
Fixed bugs:
o The default URL encoding logic was broken. Issue: 25995. Thanks to Oleg
Kalnichevski.
o Base64 chunked encoding not compliant with RFC 2045 section 2.1 CRLF.
Issue: 27781. Thanks to Gary D. Gregory.
o Hex converts illegal characters to 255. Issue: 28455.
o Metaphone now correctly handles a silent B in a word that ends in MB.
"COMB" is encoded as "KM", before this fix "COMB" was encoded as "KMB".
Issue: 28457.
o Added missing tags in Javadoc comments.
o General Javadoc improvements.
Changes:
o This version is relesed under the Apache License 2.0 , please see
LICENSE.txt. Previous versions were released under the Apache License 1.1.
o The Board recommendation to remove Javadoc author tags has been
implemented. All author tags are now "Apache Software Foundation".
Have fun!
-The commons-codec team

Binary file not shown.

Binary file not shown.

@ -0,0 +1,10 @@
#Update RosList name
#Mon Feb 08 22:15:58 CST 2021
ProjectPath=/home/xyz/workspace/ars_ws
DefaultPointX=0
RosList=WaypointReachedNotifier
AgentList=PlannerAgent,PlanDispatchAgent,MoveAgent
TaskList=DomainDescription,ProblemDescription
ProjectName=IndoorNavigationWaypointTracing
ProjectType=Deliberative
DefaultPointY=0

@ -0,0 +1,34 @@
package SampleApplication.Agent;
import SampleApplication.AgentConfiguration;
import agentBehaviourPrototype.ExecutionBehaviour;
import agentBehaviourPrototype.ReceiveDataFromAgentBehaviour;
import agentBehaviourPrototype.SendDataToAgentBehaviour;
import agentBehaviourPrototype.ReceiveDataFromROSBehaviour;
import agentEntityPrototype.RobotAgent;
import edu.wpi.rail.jrosbridge.services.std.Empty.Request;
import jade.core.AID;
public class ${entity.className}<#if entity.superclass?has_content> extends ${entity.superclass} </#if>
{
<#list entity.allRelatedElements as allReEle>
private AID ${allReEle.specificType} = new AID(AgentConfiguration.${allReEle.specificType}ID, false);
</#list>
protected void setup() {
//automatically generated
this.controller.addTopic(AgentConfiguration.actionDispatchFeedbackTopicName, AgentConfiguration.actionDispatchFeedbackTopicType);
//agent communication
<#list entity.postiveRelatedElementsWithRelation as posReEleWithRela>
this.behList.addElement(new SendDataToAgentBehaviour(this, controller, ${posReEleWithRela.specificType}, AgentConfiguration.${posReEleWithRela.relation}DataKey));
</#list>
<#list entity.negativeRelatedElementsWithRelation as negReEleWithRela>
this.behList.addElement(new ReceiveDataFromROSBehaviour(this, controller, AgentConfiguration.actionDispatchFeedbackTopicName, AgentConfiguration.${negReEleWithRela.relation}DataKey));
</#list>
addBehaviour(tbf.wrap(new ExecutionBehaviour(this, ds, this.behList)));
}
}

@ -0,0 +1,193 @@
package CodeGenerator;
import java.awt.Canvas;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class ActuatorAgentCodeGeneratorClient {
private static File javaFile = null;
public static void AgentFileGenerator(String path, DrawElement drawelement, MyCanvas cans) {
Configuration cfg = new Configuration();
try {
// 指定模板文件从何处加载的数据源,这里设置一个文件目录
cfg.setDirectoryForTemplateLoading(new File("./src/CodeGenerator"));
cfg.setObjectWrapper(new DefaultObjectWrapper());
// 获取模板文件
Template template = cfg.getTemplate("ActuatorAgent.ftl");
// 创建数据模型
Map<String, Object> root = createDataModel(path, drawelement, cans);
// 合并模板和数据模型
// 创建.java类文件
if(javaFile != null){
Writer javaWriter = new FileWriter(javaFile);
template.process(root, javaWriter);
javaWriter.flush();
System.out.println("文件生成路径:" + javaFile.getCanonicalPath());
javaWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
}
//创建数据模型
private static Map<String, Object> createDataModel(String path, DrawElement drawelement, MyCanvas cans) {
Map<String, Object> root = new HashMap<String, Object>();
Entity user = new Entity();
TbfEntity user1 = new TbfEntity();
ControllerEntity user2 = new ControllerEntity();
//user.setJavaPackage("agent"); // 创建包名
user.setClassName(drawelement.getName()); // 创建类名
user.setConstructors(false); // 是否创建构造函数
user.setSuperclass("RobotAgent");//创建父类
user.setSpecificType(drawelement.getSpecificType());
List<Property> propertyList = new ArrayList<Property>();
List<TbfEntity> tbfEntityList = new ArrayList<TbfEntity>();
List<Entity> entityList = new ArrayList<Entity>();
List<ControllerEntity> controllerEntityList = new ArrayList<ControllerEntity>();
List<DrawElementWithRelation> postiveRelatedElementsWithRelation = new ArrayList<DrawElementWithRelation>();
List<DrawElementWithRelation> negativeRelatedElementsWithRelation = new ArrayList<DrawElementWithRelation>();
List<DrawElement> allRelatedElements = new ArrayList<DrawElement>();
// 创建实体属性
Property attribute1 = new Property();
attribute1.setJavaType("static final long");
attribute1.setPropertyName("serialVersionUID");
attribute1.setPropertyType(PropertyType.Long);
// 创建实体属性(tbf)
int tbfAmount = 4; //这里输入tbf的数量
for (int i = 1; i < tbfAmount +1 ; i = i + 1) {
String tbfName = "tbf" + i;
TbfEntity tbfEntityAttribute = new TbfEntity();
tbfEntityAttribute.setClassName(tbfName);
tbfEntityAttribute.setSuperclass("ThreadedBehaviourFactory");
tbfEntityList.add(tbfEntityAttribute);
}
//TbfEntity tbfEntityAttribute2 = new TbfEntity();
//tbfEntityAttribute2.setClassName("tbf2");
//tbfEntityAttribute2.setSuperclass("ThreadedBehaviourFactory");
//创建实体属性(controller)
ControllerEntity controllerAttribute = new ControllerEntity();
controllerAttribute.setClassName("moveController");
controllerAttribute.setSuperclass("Controller");
//创建实体属性(除tbf和controller以外的属性)
Entity entityAttribute1 = new Entity();
entityAttribute1.setClassName("cameraAgent");
entityAttribute1.setSuperclass("AID");
Entity entityAttribute2 = new Entity();
entityAttribute2.setClassName("bumperAgent");
entityAttribute2.setSuperclass("AID");
Entity entityAttribute3 = new Entity();
entityAttribute3.setClassName("ds");
entityAttribute3.setSuperclass("DataStore");
propertyList.add(attribute1);
//tbfEntityList.add(tbfEntityAttribute1);
//tbfEntityList.add(tbfEntityAttribute2);
controllerEntityList.add(controllerAttribute);
entityList.add(entityAttribute1);
entityList.add(entityAttribute2);
entityList.add(entityAttribute3);
// 判断该元素是否和其他元素有箭头关系
for(DrawElement drawEleInDrawlist:cans.getDrawlist()) {
if(drawEleInDrawlist.getType() == 2){ // 是箭头线段的时候要判断是否和该元素有关
if (drawelement.getName() == drawEleInDrawlist.getDrawlist().get(0).getName()){ // 该元素是箭头线段的起始点
allRelatedElements.add(drawEleInDrawlist.getDrawlist().get(1)); //列表中存储的是箭头线段的结束点
postiveRelatedElementsWithRelation.add(new DrawElementWithRelation(drawEleInDrawlist.getDrawlist().get(1), drawEleInDrawlist.getName()));
}
else if (drawelement.getName() == drawEleInDrawlist.getDrawlist().get(1).getName()) { // 该元素是箭头线段的结束点
allRelatedElements.add(drawEleInDrawlist.getDrawlist().get(0));
negativeRelatedElementsWithRelation.add(new DrawElementWithRelation(drawEleInDrawlist.getDrawlist().get(0), drawEleInDrawlist.getName()));
}
else{}
}
}
// 将有关系的对象放到同一个列表中但不能重复为了后续生成的文件中获取交互对象id的那一行用
removeDuplicate(allRelatedElements);
// 将属性集合添加到实体对象中
user.setProperties(propertyList);
user.setEntities(entityList);
user.setPostiveRelatedElementsWithRelation(postiveRelatedElementsWithRelation); // 箭头线段的起始点在该对象
user.setNegativeRelatedElementsWithRelation(negativeRelatedElementsWithRelation); // 箭头线段的结束点在该对象
user.setAllRelatedElements(allRelatedElements); // 和该对象用箭头相关的所有对象都在该列表中
user1.setTbfentities(tbfEntityList);
user2.setControllerentities(controllerEntityList);
// 创建.java类文件
File outDirFile = new File(path + "/Agent"); // .java类文件存放的文件夹
if(!outDirFile.exists()){
outDirFile.mkdir();
}
javaFile = toJavaFilename(outDirFile, user.getClassName());
root.put("entity", user);
root.put("tbfentity",user1);
root.put("controllerentity", user2);
return root;
}
/**
* .java .javaFile
* @param outDirFile
* @param javaPackage java
* @param javaClassName java
* @return
*/
private static File toJavaFilename(File outDirFile, String javaClassName) {
File file = new File(outDirFile, javaClassName + ".java");
return file;
}
// 删除ArrayList中重复元素
public static void removeDuplicate(List<DrawElement> list) {
for (int i = 0; i < list.size() - 1; i++) {
for (int j = list.size() - 1; j > i; j--) {
if (list.get(j).equals(list.get(i))) {
list.remove(j);
}
}
}
}
}

@ -0,0 +1,158 @@
package CodeGenerator;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class AgentCodeGeneratorClient {
private static File javaFile = null;
public static void main(String[] args) {
Configuration cfg = new Configuration();
try {
// 指定模板文件从何处加载的数据源,这里设置一个文件目录
cfg.setDirectoryForTemplateLoading(new File("./src/CodeGenerator"));
cfg.setObjectWrapper(new DefaultObjectWrapper());
// 获取模板文件
Template template = cfg.getTemplate("agent.ftl");
// 创建数据模型
Map<String, Object> root = createDataModel(null, 0);
// 合并模板和数据模型
// 创建.java类文件
if(javaFile != null){
Writer javaWriter = new FileWriter(javaFile);
template.process(root, javaWriter);
javaWriter.flush();
System.out.println("文件生成路径:" + javaFile.getCanonicalPath());
javaWriter.close();
}
// 输出到Console控制台
Writer out = new OutputStreamWriter(System.out);
template.process(root, out);
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
}
//创建数据模型
private static Map<String, Object> createDataModel(String agentName, int tbf) {
Map<String, Object> root = new HashMap<String, Object>();
Entity user = new Entity();
TbfEntity user1 = new TbfEntity();
ControllerEntity user2 = new ControllerEntity();
user.setJavaPackage("agent"); // 创建包名
user.setClassName(agentName + "Agent"); // 创建类名
user.setConstructors(false); // 是否创建构造函数
user.setSuperclass("Agent");//创建父类
List<Property> propertyList = new ArrayList<Property>();
List<TbfEntity> tbfEntityList = new ArrayList<TbfEntity>();
List<Entity> entityList = new ArrayList<Entity>();
List<ControllerEntity> controllerEntityList = new ArrayList<ControllerEntity>();
// 创建实体属性
Property attribute1 = new Property();
attribute1.setJavaType("static final long");
attribute1.setPropertyName("serialVersionUID");
attribute1.setPropertyType(PropertyType.Long);
// 创建实体属性(tbf)
//int tbfAmount = 4; //这里输入tbf的数量
for (int i = 1; i < tbf +1 ; i = i + 1) {
String tbfName = "tbf" + i;
TbfEntity tbfEntityAttribute = new TbfEntity();
tbfEntityAttribute.setClassName(tbfName);
tbfEntityAttribute.setSuperclass("ThreadedBehaviourFactory");
tbfEntityList.add(tbfEntityAttribute);
}
//TbfEntity tbfEntityAttribute2 = new TbfEntity();
//tbfEntityAttribute2.setClassName("tbf2");
//tbfEntityAttribute2.setSuperclass("ThreadedBehaviourFactory");
//创建实体属性(controller)
ControllerEntity controllerAttribute = new ControllerEntity();
controllerAttribute.setClassName("moveController");
controllerAttribute.setSuperclass("Controller");
//创建实体属性(除tbf和controller以外的属性)
Entity entityAttribute1 = new Entity();
entityAttribute1.setClassName("cameraAgent");
entityAttribute1.setSuperclass("AID");
Entity entityAttribute2 = new Entity();
entityAttribute2.setClassName("bumperAgent");
entityAttribute2.setSuperclass("AID");
Entity entityAttribute3 = new Entity();
entityAttribute3.setClassName("ds");
entityAttribute3.setSuperclass("DataStore");
propertyList.add(attribute1);
//tbfEntityList.add(tbfEntityAttribute1);
//tbfEntityList.add(tbfEntityAttribute2);
controllerEntityList.add(controllerAttribute);
entityList.add(entityAttribute1);
entityList.add(entityAttribute2);
entityList.add(entityAttribute3);
// 将属性集合添加到实体对象中
user.setProperties(propertyList);
user.setEntities(entityList);
user1.setTbfentities(tbfEntityList);
user2.setControllerentities(controllerEntityList);
// 创建.java类文件
File outDirFile = new File("./agent-generator");
if(!outDirFile.exists()){
outDirFile.mkdir();
}
javaFile = toJavaFilename(outDirFile, user.getJavaPackage(), user.getClassName());
root.put("entity", user);
root.put("tbfentity",user1);
root.put("controllerentity", user2);
return root;
}
/**
* .java .javaFile
* @param outDirFile
* @param javaPackage java
* @param javaClassName java
* @return
*/
private static File toJavaFilename(File outDirFile, String javaPackage, String javaClassName) {
String packageSubPath = javaPackage.replace('.', '/');
File packagePath = new File(outDirFile, packageSubPath);
File file = new File(packagePath, javaClassName + ".java");
if(!packagePath.exists()){
packagePath.mkdirs();
}
return file;
}
}

@ -0,0 +1,88 @@
package agentApplication2;
import jade.core.Profile;
import jade.core.ProfileImpl;
import jade.wrapper.AgentController;
import jade.wrapper.StaleProxyException;
public class AgentConfiguration {
//-----------------------------------------user inputs------------------------------------------------------//
//Agent names
public static final String moveAgentID = "moveAgent";
public static final String taskPlanningAgentID = "taskPlanningAgent";
public static final String dispatchAgentID = "dispatchAgent";
//Planning model paths
public static final String domainFilePath = "/home/ys/eclipse-workspace/AutoRobot/PDDLFiles/domain_turtlebot.pddl";
public static final String problemFilePath = "/home/ys/eclipse-workspace/AutoRobot/PDDLFiles/problem_turtlebot.pddl";
//ROS services
public static final String problemGenerationServiceName = "/rosplan_problem_interface/problem_generation_server";
public static final String problemGenerationServiceType = "std_srvs/Empty";
public static final String planServiceName = "/rosplan_planner_interface/planning_server";
public static final String planServiceType = "std_srvs/Empty";
public static final String parseServiceName = "/rosplan_parsing_interface/parse_plan";
public static final String parseServiceType = "std_srvs/Empty";
public static final String dispatchServiceName = "/rosplan_plan_dispatcher/dispatch_plan";
public static final String dispatchServiceType = "std_srvs/Empty";
//ROS topics
public static final String actionDispatchFeedbackTopicName = "/rosplan_plan_dispatcher/action_feedback";
public static final String actionDispatchFeedbackTopicType = "rosplan_dispatch_msgs/ActionFeedback";
//DataStore keys
public static final String planDispatchDataKey = "planDispatch";
public static final String planFeedbackDataKey = "planFeedback";
public static final String actionDispatchDataKey = "actionDispatch";
public static String actionFeedbackDataKey = "actionFeedback";
public static void main(String[] args) throws InterruptedException {
//automatically generated
jade.core.Runtime rt = jade.core.Runtime.instance();
Profile pContainer = new ProfileImpl(null, 8888, null);
rt.setCloseVM(true);
Profile pMain = new ProfileImpl(null, 1099, null);
pMain.setParameter(Profile.SERVICES, "jade.core.messaging.TopicManagementService");
System.out.println("Launching a whole in-process platform..." + pMain);
jade.wrapper.AgentContainer mc = rt.createMainContainer(pMain);
jade.wrapper.AgentContainer agentContainer = rt.createAgentContainer(pContainer);
System.out.println("continue");
//Create Agents
try {
AgentController moveAgent = agentContainer.createNewAgent(AgentConfiguration.moveAgentID, "AutoRobot.agentApplication2.MoveAgent", null);
moveAgent.start();
} catch (StaleProxyException e2) {
e2.printStackTrace();
}
try{
AgentController dispatchAgent = agentContainer.createNewAgent(AgentConfiguration.dispatchAgentID, "AutoRobot.agentApplication2.DispatchAgent", null);
dispatchAgent.start();
} catch (StaleProxyException e) {
e.printStackTrace();
}
try{
AgentController taskPlanningAgent = agentContainer.createNewAgent(AgentConfiguration.taskPlanningAgentID, "AutoRobot.agentApplication2.TaskPlanningAgent", null);
taskPlanningAgent.start();
} catch (StaleProxyException e) {
e.printStackTrace();
}
//-------------------------------------------------------------------------------------------------------------------------------------------//
}
}

@ -0,0 +1,174 @@
package CodeGenerator;
import java.awt.Canvas;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class AgentConfigurationCodeGeneratorClient {
private static File javaFile = null;
public static void AgentFileGenerator(String path) {
Configuration cfg = new Configuration();
try {
// 指定模板文件从何处加载的数据源,这里设置一个文件目录
cfg.setDirectoryForTemplateLoading(new File("./src/CodeGenerator"));
cfg.setObjectWrapper(new DefaultObjectWrapper());
// 获取模板文件
Template template = cfg.getTemplate("AgentConfiguration.ftl");
// 创建数据模型
Map<String, Object> root = createDataModel(path);
// 合并模板和数据模型
// 创建.java类文件
if(javaFile != null){
Writer javaWriter = new FileWriter(javaFile);
template.process(root, javaWriter);
javaWriter.flush();
System.out.println("文件生成路径:" + javaFile.getCanonicalPath());
javaWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
}
//创建数据模型
private static Map<String, Object> createDataModel(String path) {
Map<String, Object> root = new HashMap<String, Object>();
Entity user = new Entity();
TbfEntity user1 = new TbfEntity();
ControllerEntity user2 = new ControllerEntity();
user.setClassName("AgentConfiguration");
/*
//user.setJavaPackage("agent"); // 创建包名
user.setClassName(drawelement.getName()); // 创建类名
user.setConstructors(false); // 是否创建构造函数
user.setSuperclass("RobotAgent");//创建父类
user.setSpecificType(drawelement.getSpecificType());
List<Property> propertyList = new ArrayList<Property>();
List<TbfEntity> tbfEntityList = new ArrayList<TbfEntity>();
List<Entity> entityList = new ArrayList<Entity>();
List<ControllerEntity> controllerEntityList = new ArrayList<ControllerEntity>();
// 创建实体属性
Property attribute1 = new Property();
attribute1.setJavaType("static final long");
attribute1.setPropertyName("serialVersionUID");
attribute1.setPropertyType(PropertyType.Long);
// 创建实体属性(tbf)
int tbfAmount = 4; //这里输入tbf的数量
for (int i = 1; i < tbfAmount +1 ; i = i + 1) {
String tbfName = "tbf" + i;
TbfEntity tbfEntityAttribute = new TbfEntity();
tbfEntityAttribute.setClassName(tbfName);
tbfEntityAttribute.setSuperclass("ThreadedBehaviourFactory");
tbfEntityList.add(tbfEntityAttribute);
}
//创建实体属性(controller)
ControllerEntity controllerAttribute = new ControllerEntity();
controllerAttribute.setClassName("moveController");
controllerAttribute.setSuperclass("Controller");
//创建实体属性(除tbf和controller以外的属性)
Entity entityAttribute1 = new Entity();
entityAttribute1.setClassName("cameraAgent");
entityAttribute1.setSuperclass("AID");
Entity entityAttribute2 = new Entity();
entityAttribute2.setClassName("bumperAgent");
entityAttribute2.setSuperclass("AID");
Entity entityAttribute3 = new Entity();
entityAttribute3.setClassName("ds");
entityAttribute3.setSuperclass("DataStore");
propertyList.add(attribute1);
//tbfEntityList.add(tbfEntityAttribute1);
//tbfEntityList.add(tbfEntityAttribute2);
controllerEntityList.add(controllerAttribute);
entityList.add(entityAttribute1);
entityList.add(entityAttribute2);
entityList.add(entityAttribute3);
// 将属性集合添加到实体对象中
user.setProperties(propertyList);
user.setEntities(entityList);
user1.setTbfentities(tbfEntityList);
user2.setControllerentities(controllerEntityList);
*/
// 创建.java类文件
File outDirFile = new File(path); // .java类文件存放的文件夹
if(!outDirFile.exists()){
outDirFile.mkdir();
}
javaFile = toJavaFilename(outDirFile, user.getClassName());
root.put("entity", user);
root.put("tbfentity",user1);
root.put("controllerentity", user2);
return root;
}
/**
* .java .javaFile
* @param outDirFile
* @param javaPackage java
* @param javaClassName java
* @return
*/
private static File toJavaFilename(File outDirFile, String javaClassName) {
File file = new File(outDirFile, javaClassName + ".java");
return file;
}
// 删除ArrayList中重复元素
public static void removeDuplicate(List<DrawElement> list) {
for (int i = 0; i < list.size() - 1; i++) {
for (int j = list.size() - 1; j > i; j--) {
if (list.get(j).equals(list.get(i))) {
list.remove(j);
}
}
}
}
}

@ -0,0 +1,128 @@
package CodeGenerator;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JComboBox;
public class AgentGeneratorDialog extends JFrame implements ActionListener {
private JTextField textField;
private JTextField textField_1;
private JTextField textField_2;
private JButton createAgentButton;
private JComboBox <String> comboBoxAgentType;
String mypath;
/**
* Create the panel.
*/
public AgentGeneratorDialog(String path) {
super("Create Agent");
this.mypath = path;
System.out.println("sdsd");
getContentPane().setLayout(null);
this.setBounds(300, 300, 450, 180);
JLabel lblAgentName = new JLabel("Agent Name:");
lblAgentName.setBounds(113, 24, 81, 16);
getContentPane().add(lblAgentName);
/*
JLabel lblNumberOfBehavior = new JLabel("Number of Behavior:");
lblNumberOfBehavior.setBounds(66, 57, 128, 16);
this.add(lblNumberOfBehavior);
JLabel lblNumberOfConnect = new JLabel("Number of Connect Agent:");
lblNumberOfConnect.setBounds(26, 93, 168, 16);
this.add(lblNumberOfConnect);
*/
textField = new JTextField();
textField.setBounds(206, 19, 217, 26);
getContentPane().add(textField);
textField.setColumns(10);
/*
textField_1 = new JTextField();
textField_1.setBounds(206, 52, 217, 26);
this.add(textField_1);
textField_1.setColumns(10);
textField_2 = new JTextField();
textField_2.setBounds(206, 88, 217, 26);
this.add(textField_2);
textField_2.setColumns(10);
*/
createAgentButton = new JButton("Create Agent");
//createAgentButton.setBounds(177, 130, 117, 29);
createAgentButton.setBounds(306, 98, 117, 29);
getContentPane().add(createAgentButton);
comboBoxAgentType = new JComboBox();
comboBoxAgentType.setBounds(206, 59, 217, 27);
getContentPane().add(comboBoxAgentType);
comboBoxAgentType.addItem("Planner Agent");
comboBoxAgentType.addItem("Dispatcher Agent");
comboBoxAgentType.addItem("Sensor Agent");
comboBoxAgentType.addItem("Actuator Agent");
JLabel lblAgentType = new JLabel("Agent Type:");
lblAgentType.setBounds(123, 63, 75, 16);
getContentPane().add(lblAgentType);
createAgentButton.addActionListener(this);
/*
JButton cancelButton = new JButton("Cancel");
cancelButton.setBounds(306, 130, 117, 29);
add(cancelButton);
cancelButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
createAgentDialog.setVisible(false);
}
});
*/
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == this.createAgentButton) {
/*
String name = this.textField.getText();
//String tbfstring = this.textField_1.getText();
//int tbf = Integer.parseInt(tbfstring);
String type = (String)this.comboBoxAgentType.getSelectedItem();
if (type == "Planner Agent")
{
PlannerAgentCodeGeneratorClient.AgentFileGenerator(mypath, name);
//System.out.println("Plan Agent");
}
else if (type == "Dispatcher Agent")
{
DispatcherAgentCodeGeneratorClient.AgentFileGenerator(mypath, name);
//System.out.println("Dispatch Agent");
}
else if (type == "Sensor Agent")
{
SensorAgentCodeGeneratorClient.AgentFileGenerator(mypath, name);
//System.out.println("Sensor Agent");
}
else
{
SensorAgentCodeGeneratorClient.AgentFileGenerator(mypath, name);
//System.out.println("Actuator Agent");
}
this.dispose();
//this.setVisible(false);
*/
}
}
}

@ -0,0 +1,259 @@
package CodeGenerator;
import javax.swing.*;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JRadioButton;
import java.awt.Component;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.border.LineBorder;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.io.File;
import java.awt.event.ActionEvent;
public class AutoRobotAssistant extends JFrame {
private JPanel contentPane;
private final JPanel panel = new JPanel();
private JTextField newNameText;
private JTextField openLocationText;
private JTextField textField_3;
private JTextField textField_5;
private JTextField textField_6;
private JRadioButton RadioButtonNew;
private JRadioButton RadioButtonOpen;
private JTextField newLocationText;
private JFileChooser chooser;
private Icon icon;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
//try {
// AutoRobotAssistant frame = new AutoRobotAssistant();
// frame.setVisible(true);
//} catch (Exception e) {
// e.printStackTrace();
//}
AutoRobotAssistant frame = new AutoRobotAssistant();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
/**
* Create the frame.
*/
public AutoRobotAssistant() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 812, 470);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
panel.setBorder(new LineBorder(Color.GRAY));
panel.setBounds(0, 0, 450, 188);
contentPane.add(panel);
panel.setLayout(null);
chooser = new JFileChooser();
JLabel lblProject = new JLabel("Application");
lblProject.setBounds(6, 7, 72, 16);
panel.add(lblProject);
JLabel newNameLabel = new JLabel("Name");
newNameLabel.setBounds(96, 33, 41, 16);
panel.add(newNameLabel);
newNameText = new JTextField();
newNameText.setBounds(149, 28, 295, 26);
panel.add(newNameText);
newNameText.setColumns(10);
JLabel newLocationLabel = new JLabel("Path");
newLocationLabel.setBounds(96, 64, 41, 16);
panel.add(newLocationLabel);
JButton btnNewButton = new JButton("Create and Open");
btnNewButton.setBounds(314, 90, 130, 29);
panel.add(btnNewButton);
openLocationText = new JTextField();
openLocationText.setColumns(10);
openLocationText.setBounds(149, 121, 280, 26);
panel.add(openLocationText);
JButton btnOpen = new JButton("Open");
btnOpen.setBounds(314, 152, 130, 29);
panel.add(btnOpen);
JLabel openLocationLabel = new JLabel("Path");
openLocationLabel.setBounds(96, 126, 41, 16);
panel.add(openLocationLabel);
JButton pathButton_1 = new JButton("..");
pathButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
chooser.setCurrentDirectory(new File("."));
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setDialogTitle("Choose Application Location");
int result = chooser.showOpenDialog(AutoRobotAssistant.this);
if (result == JFileChooser.APPROVE_OPTION)
{
String path = chooser.getSelectedFile().getPath();
newLocationText.setText(path);
}
}
});
pathButton_1.setBounds(429, 64, 15, 16);
panel.add(pathButton_1);
ButtonGroup group = new ButtonGroup();
JRadioButton RadioButtonNew = new JRadioButton("New");
RadioButtonNew.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
newNameLabel.setEnabled(true);
newNameText.setEnabled(true);
newLocationLabel.setEnabled(true);
newLocationText.setEnabled(true);
pathButton_1.setEnabled(true);
openLocationLabel.setEnabled(false);
openLocationText.setEnabled(false);
}
});
RadioButtonNew.setBounds(16, 29, 68, 23);
panel.add(RadioButtonNew);
group.add(RadioButtonNew);
JRadioButton RadioButtonOpen = new JRadioButton("Open");
RadioButtonOpen.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
newNameLabel.setEnabled(false);
newNameText.setEnabled(false);
newLocationLabel.setEnabled(false);
newLocationText.setEnabled(false);
pathButton_1.setEnabled(false);
openLocationLabel.setEnabled(true);
openLocationText.setEnabled(true);
}
});
RadioButtonOpen.setBounds(16, 122, 68, 23);
panel.add(RadioButtonOpen);
group.add(RadioButtonOpen);
newLocationText = new JTextField();
//LocationText_1.setText();
newLocationText.setColumns(10);
newLocationText.setBounds(149, 59, 280, 26);
panel.add(newLocationText);
JButton pathButton_2 = new JButton("..");
pathButton_2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
chooser.setCurrentDirectory(new File("."));
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setDialogTitle("Choose Application Location");
int result = chooser.showOpenDialog(AutoRobotAssistant.this);
if (result == JFileChooser.APPROVE_OPTION)
{
String path = chooser.getSelectedFile().getPath();
openLocationText.setText(path);
}
}
});
pathButton_2.setBounds(429, 127, 15, 16);
panel.add(pathButton_2);
JPanel panel_1 = new JPanel();
panel_1.setBorder(new LineBorder(new Color(128, 128, 128)));
panel_1.setBounds(0, 188, 450, 188);
contentPane.add(panel_1);
panel_1.setLayout(null);
JLabel lblCodegenerator = new JLabel("Agent Generator");
lblCodegenerator.setBounds(6, 6, 110, 16);
panel_1.add(lblCodegenerator);
JLabel lblPackageName = new JLabel("Agent Name");
lblPackageName.setBounds(95, 34, 77, 16);
panel_1.add(lblPackageName);
textField_3 = new JTextField();
textField_3.setBounds(196, 29, 248, 26);
panel_1.add(textField_3);
textField_3.setColumns(10);
JLabel lblNumberOfTbf = new JLabel("Number of rbehavior");
lblNumberOfTbf.setBounds(43, 85, 130, 21);
panel_1.add(lblNumberOfTbf);
textField_5 = new JTextField();
textField_5.setColumns(10);
textField_5.setBounds(196, 115, 248, 26);
panel_1.add(textField_5);
JLabel lblNumberOfConnect = new JLabel("Number of Connect Agent");
lblNumberOfConnect.setBounds(8, 118, 164, 21);
panel_1.add(lblNumberOfConnect);
textField_6 = new JTextField();
textField_6.setColumns(10);
textField_6.setBounds(196, 82, 248, 26);
panel_1.add(textField_6);
JButton btnCreateAgent = new JButton("Create Diagram");
btnCreateAgent.setBounds(314, 153, 130, 29);
panel_1.add(btnCreateAgent);
JButton button = new JButton("Create Agent");
button.setBounds(193, 153, 130, 29);
panel_1.add(button);
JPanel panel_2 = new JPanel();
panel_2.setBorder(new LineBorder(Color.GRAY));
panel_2.setBounds(0, 375, 450, 73);
contentPane.add(panel_2);
panel_2.setLayout(null);
JLabel lblHelp = new JLabel("Help");
lblHelp.setBounds(6, 6, 61, 16);
panel_2.add(lblHelp);
JButton btnNewButton_1 = new JButton("Read Me");
btnNewButton_1.setBounds(60, 34, 154, 29);
panel_2.add(btnNewButton_1);
JButton btnGithub = new JButton("Github");
btnGithub.setBounds(240, 34, 154, 29);
panel_2.add(btnGithub);
JPanel panel_diagram = new JPanel();
panel_diagram.setBounds(450, 0, 362, 448);
contentPane.add(panel_diagram);
panel_diagram.setLayout(null);
JLabel diagram = new JLabel("New label");
icon = new ImageIcon("/Users/mac/Desktop/pic.png");
diagram.setIcon(icon);
diagram.setBounds(0, 6, 362,442);
//diagram.setBounds(0, 6, icon.getIconWidth(),icon.getIconHeight());
panel_diagram.add(diagram, new Integer(Integer.MIN_VALUE));
}
}

@ -0,0 +1,752 @@
package CodeGenerator;
import java.io.File;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.Menu;
import java.awt.MenuItem;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.*;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.border.BevelBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import com.sun.javafx.application.PlatformImpl;
import com.sun.media.jfxmediaimpl.platform.Platform;
import com.sun.prism.Image;
import edu.wpi.rail.jrosbridge.messages.std.Bool;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.web.WebView;
import javax.swing.JFileChooser;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JList;
import javax.swing.JPopupMenu;
import javax.swing.JTree;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.event.TreeSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Enumeration;
import java.util.List;
import javax.swing.JScrollBar;
import javax.swing.JToolBar;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import java.awt.event.KeyEvent;
import java.awt.event.InputEvent;
import java.awt.Rectangle;
import java.awt.Dimension;
import javax.swing.border.CompoundBorder;
import javax.swing.border.LineBorder;
import java.awt.Color;
import javax.swing.border.MatteBorder;
import javax.swing.JLayeredPane;
import javax.swing.JTabbedPane;
import javax.swing.border.EtchedBorder;
import javax.swing.UIManager;
import java.awt.SystemColor;
import javax.swing.border.SoftBevelBorder;
public class AutoRobotCodeGenerator extends JFrame {
private JPanel contentPane;
private OpenApplication openDialog = null;
private NewApplication newDialog = null;
private AgentGeneratorDialog agentGeneratorDialog = null;
static DefaultTreeModel newModel;
static IconNode Node;
private int editorPaneIndex = 0;
// private String curApplicationPath = "src//SampleApplication"; //
// 未初始化的时候默认为
private String curApplicationPath = (ReadTxt
.readFile(this.getClass().getResource("").getPath() + "userApplicationPath.ini")).get(0);
private JScrollPane treejslp;
private JTree tree;
private JTabbedPane tabbedPane;
private JTabbedPane editorPane;
private DrawJPanel DesinModelPanel = new DrawJPanel(curApplicationPath);
// private EditorJPanel EditorPanel = new EditorJPanel();
private boolean modifiedFlag = false; // 在当前项目中有新文件被添加时该值会变为true提示刷新树状目录结构图
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
AutoRobotCodeGenerator frame = new AutoRobotCodeGenerator();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public AutoRobotCodeGenerator() {
setTitle("AutoRobot Code Generator");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 1000, 800);
setResizable(false);
// ---- menubar
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu menuFile = new JMenu("File");
menuBar.add(menuFile);
JMenuItem menuItemNewApplication = new JMenuItem("New Application");
menuItemNewApplication.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
creatApplicationMethod();
}
});
menuItemNewApplication.setAccelerator(KeyStroke.getKeyStroke("ctrl N"));
menuFile.add(menuItemNewApplication);
// menu 打开项目
JMenuItem menuItemOpenApplication = new JMenuItem("Open Application");
menuItemOpenApplication.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
openApplicationMethod();
}
});
menuItemOpenApplication.setAccelerator(KeyStroke.getKeyStroke("ctrl O"));
menuFile.add(menuItemOpenApplication);
/*
* JMenu menuEdit = new JMenu("Edit"); menuBar.add(menuEdit);
*
* JMenuItem menuItemCut = new JMenuItem("Cut");
* menuItemCut.setMnemonic(KeyEvent.VK_CUT); menuEdit.add(menuItemCut);
*
* JMenuItem menuItemCopy = new JMenuItem("Copy");
* menuItemCopy.setMnemonic(KeyEvent.VK_COPY); menuEdit.add(menuItemCopy);
*
* JMenuItem menuItemPaste = new JMenuItem("Paste");
* menuItemPaste.setMnemonic(KeyEvent.VK_PASTE); menuEdit.add(menuItemPaste);
*/
JMenu menuModel = new JMenu("Model");
menuBar.add(menuModel);
// menu 创建类图
JMenuItem menuItemCreateClassDiagram = new JMenuItem("Create Class Diagram");
menuItemCreateClassDiagram.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, InputEvent.CTRL_MASK));
menuModel.add(menuItemCreateClassDiagram);
/*
* JMenuItem menuItemRefreshModel = new JMenuItem("Refresh Model");
* menuItemRefreshModel.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R,
* InputEvent.CTRL_MASK)); menuModel.add(menuItemRefreshModel);
*
* JMenu menuCode = new JMenu("Code"); menuBar.add(menuCode);
*
* JMenuItem menuItemCreateAgent = new JMenuItem("Create Agent");
* menuItemCreateAgent.addActionListener(new ActionListener() { public void
* actionPerformed(ActionEvent event) { new
* AgentGeneratorDialog(curApplicationPath); System.out.println("add angent"); }
* }); menuItemCreateAgent.setAccelerator(KeyStroke.getKeyStroke("ctrl A"));
* menuCode.add(menuItemCreateAgent);
*
* JMenuItem menuItemCreateRos = new JMenuItem("Create ROS Node");
* menuItemCreateRos.addActionListener(new ActionListener() { public void
* actionPerformed(ActionEvent event) { new
* ROSNodeGeneratorDialog(curApplicationPath); } }); menuItemCreateRos
* .setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_MASK |
* InputEvent.SHIFT_MASK)); menuCode.add(menuItemCreateRos);
*
* JMenuItem menuItemCreatePlanning = new JMenuItem("Create Planning Node");
* menuItemCreatePlanning.addActionListener(new ActionListener() { public void
* actionPerformed(ActionEvent event) { new
* PlanningNodeGeneratorDialog(curApplicationPath); } });
* menuItemCreatePlanning.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P,
* InputEvent.CTRL_MASK)); menuCode.add(menuItemCreatePlanning);
*/
/*
* JMenu menuHelp = new JMenu("Help"); menuBar.add(menuHelp);
*
* JMenuItem mntmReadMe = new JMenuItem("Read Me"); menuHelp.add(mntmReadMe);
*
* JMenuItem mntmGithub = new JMenuItem("Github"); menuHelp.add(mntmGithub);
*/
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
// 添加滚动窗口
treejslp = new JScrollPane();
treejslp.setBorder(null);
treejslp.setBounds(2, 35, 250, 725);
contentPane.add(treejslp);
treejslp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
treejslp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
// --------------toolbar
JToolBar toolBar = new JToolBar();
toolBar.setBackground(SystemColor.window);
toolBar.setBorder(new SoftBevelBorder(BevelBorder.RAISED, null, null, null, null));
toolBar.setEnabled(false);
toolBar.setBounds(0, 0, 1005, 35);
toolBar.setFloatable(false);
contentPane.add(toolBar);
// toolbar 创建项目
JButton newApplicationIcon = new JButton();
newApplicationIcon.setBorder(new EmptyBorder(0, 6, 0, 4));
newApplicationIcon.setIcon(new ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/new.png")));
newApplicationIcon.setToolTipText("New Application");
newApplicationIcon.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
creatApplicationMethod();
}
});
toolBar.add(newApplicationIcon);
// toolbar 打开项目
JButton openApplicationIcon = new JButton();
openApplicationIcon.setBorder(new EmptyBorder(0, 4, 0, 4));
openApplicationIcon.setIcon(new ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/open.png")));
openApplicationIcon.setToolTipText("Open Application");
openApplicationIcon.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
openApplicationMethod();
}
});
toolBar.add(openApplicationIcon);
/*
* toolbar JButton cutIcon = new JButton(); cutIcon.setBorder(new
* EmptyBorder(0, 4, 0, 4)); cutIcon.setIcon(new
* ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/cut.png")));
* cutIcon.setToolTipText("Cut"); // cutIcon.setBorder(new
* BevelBorder(BevelBorder.RAISED)); toolBar.add(cutIcon);
*
* JButton copyIcon = new JButton(); copyIcon.setBorder(new EmptyBorder(0, 4, 0,
* 4)); copyIcon.setIcon(new
* ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/copy.png")));
* copyIcon.setToolTipText("Copy"); // copyIcon.setBorder(new
* BevelBorder(BevelBorder.RAISED)); toolBar.add(copyIcon);
*
* JButton pasteIcon = new JButton(); pasteIcon.setBorder(new EmptyBorder(0, 4,
* 0, 4)); pasteIcon.setIcon(new
* ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/paste.png")));
* pasteIcon.setToolTipText("Paste"); // pasteIcon.setBorder(new
* BevelBorder(BevelBorder.RAISED)); toolBar.add(pasteIcon);
*
* toolBar.addSeparator();
*/
// toolbar 刷新类图按钮
JButton modelIcon = new JButton();
modelIcon.setBorder(new EmptyBorder(0, 4, 0, 4));
modelIcon.setIcon(new ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/model.png")));
modelIcon.setToolTipText("Refresh Class Diagram");
// modelIcon.setBorder(new BevelBorder(BevelBorder.RAISED));
modelIcon.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
System.out.println("刷新类图按钮点击");
GramJPanell gjp = new GramJPanell(curApplicationPath);
JScrollPane jslp = new JScrollPane(gjp);
tabbedPane.setComponentAt(0, jslp); // 第0个选项卡内容设为jslp
}
});
toolBar.add(modelIcon);
// toolbar 刷新按钮
JButton refreshIcon = new JButton();
refreshIcon.setBorder(new EmptyBorder(0, 4, 0, 4));
refreshIcon.setIcon(new ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/refresh.png")));
refreshIcon.setToolTipText("Refresh Tree Model");
// refreshIcon.setBorder(new BevelBorder(BevelBorder.RAISED));
toolBar.add(refreshIcon);
refreshIcon.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
refreshTree();
reloadPanelMethod();
}
});
toolBar.addSeparator();
/*
* //toolbar create angent JButton createAgentIcon = new JButton();
* createAgentIcon.setBorder(new EmptyBorder(0, 4, 0, 4));
* createAgentIcon.setIcon(new
* ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/addagent.png")));
* createAgentIcon.addActionListener(new ActionListener() { public void
* actionPerformed(ActionEvent e) { new
* AgentGeneratorDialog(curApplicationPath); System.out.println("add angent");
*
* } }); createAgentIcon.setToolTipText("Create Agent"); //
* createAgentIcon.setBorder(new BevelBorder(BevelBorder.RAISED));
* toolBar.add(createAgentIcon);
*
* //toolbar create rosbode JButton createROSNodeIcon = new JButton();
* createROSNodeIcon.setBorder(new EmptyBorder(0, 4, 0, 4));
* createROSNodeIcon.setIcon(new
* ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/addrosnode.png")))
* ; createROSNodeIcon.addActionListener(new ActionListener() { public void
* actionPerformed(ActionEvent event) { new
* ROSNodeGeneratorDialog(curApplicationPath); } });
* createROSNodeIcon.setToolTipText("Create ROS Node"); //
* createROSNodeIcon.setBorder(new BevelBorder(BevelBorder.RAISED));
* toolBar.add(createROSNodeIcon);
*
*
* //toolbar create planning JButton createPlanningIcon = new JButton();
* createPlanningIcon.setBorder(new EmptyBorder(0, 4, 0, 4)); createPlanningIcon
* .setIcon(new ImageIcon(AutoRobotCodeGenerator.class.getResource(
* "/icon1/addplanningnode.png"))); createPlanningIcon.addActionListener(new
* ActionListener() { public void actionPerformed(ActionEvent event) { new
* PlanningNodeGeneratorDialog(curApplicationPath); } });
* createPlanningIcon.setToolTipText("Create Planning Node"); //
* createPlanningIcon.setBorder(new BevelBorder(BevelBorder.RAISED));
* toolBar.add(createPlanningIcon); toolBar.addSeparator();
*/
/*
* JButton helpIcon = new JButton(); helpIcon.setBorder(new EmptyBorder(0, 4, 0,
* 4)); helpIcon.setIcon(new
* ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/help.png")));
* helpIcon.setToolTipText("Help"); // helpIcon.setBorder(new
* BevelBorder(BevelBorder.RAISED)); toolBar.add(helpIcon);
*/
// add compile button ???
JButton compileIcon = new JButton();
compileIcon.setBorder(new EmptyBorder(0, 4, 0, 4));
compileIcon.setIcon(new ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/compile.png")));
compileIcon.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
Thread thread = new Thread() {
public void run() {
System.out.println();
String comd = "/bin/bash " + this.getClass().getResource("/Shells/").getPath() + "make.sh";
Process proc = null;
StringBuffer stringBuffer = new StringBuffer();
BufferedReader bufferedReader = null;
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:SS ");
try {
proc = Runtime.getRuntime().exec(comd);
if (proc != null) {
stringBuffer.append("进程号:").append(proc.toString()).append("\r\n");
// bufferedReader用于读取Shell的输出内容
bufferedReader = new BufferedReader(new InputStreamReader(proc.getInputStream()), 1024);
proc.waitFor();
} else {
stringBuffer.append("没有pid\r\n");
}
// stringBuffer.append(dateFormat.format(new Date())).append(
// "Shell命令执行完毕\r\n执行结果为\r\n");
String line = null;
while (bufferedReader != null && (line = bufferedReader.readLine()) != null) {
stringBuffer.append(line).append("\r\n");
}
System.out.println("stringBuffer:" + stringBuffer);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
proc.waitFor();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
};
thread.start();
}
});
compileIcon.setToolTipText("Compile");
toolBar.add(compileIcon);
// add run button ???
JButton runIcon = new JButton();
runIcon.setBorder(new EmptyBorder(0, 4, 0, 4));
runIcon.setIcon(new ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/run.png")));
runIcon.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
Thread thread = new Thread() {
public void run() {
String comd = "/bin/bash " + this.getClass().getResource("/Shells/").getPath() + "run.sh";
Process proc = null;
try {
proc = Runtime.getRuntime().exec(comd);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
proc.waitFor();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
};
thread.start();
}
});
runIcon.setToolTipText("Run");
toolBar.add(runIcon);
// add monitor button ???
JButton monitorIcon = new JButton();
monitorIcon.setBorder(new EmptyBorder(0, 4, 0, 4));
monitorIcon.setIcon(new ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/monitor.png")));
monitorIcon.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
Thread thread = new Thread() {
public void run() {
String comd = "/bin/bash " + "/home/ys/eclipse-workspace/TestPythonJava/src/tt.sh";
Process proc = null;
try {
proc = Runtime.getRuntime().exec(comd);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
proc.waitFor();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
};
thread.start();
}
});
monitorIcon.setToolTipText("Monitor");
toolBar.add(monitorIcon);
// 创建文本编辑
/*
* editorPane = new JTabbedPane(JTabbedPane.TOP);
* editorPane.setBackground(Color.WHITE); editorPane.setBounds(254, 36, 795,
* 725); contentPane.add(editorPane);
*/
// 创建总选项卡
tabbedPane = new JTabbedPane(JTabbedPane.TOP);
tabbedPane.setBackground(Color.WHITE);
tabbedPane.setBounds(254, 36, 744, 725);
//tabbedPane.setBounds(1054, 36, 744, 725);
contentPane.add(tabbedPane);
// 创建Class Diagram选项卡
/*
* JScrollPane jslp = new JScrollPane (); tabbedPane.addTab("Class Diagram",
* null, jslp, null);
* jslp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
* jslp.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
*/
GramJPanell gjp = new GramJPanell(curApplicationPath);
JScrollPane jslp = new JScrollPane(gjp);
jslp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
jslp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
tabbedPane.addTab("Class Diagram", null, jslp, null);
tabbedPane.addTab("Design Model", null, DesinModelPanel, null);
// -- 启动调用
refreshTree();
reloadPanelMethod();
}
// 定时器,判断是否执行刷新,可定时执行刷新任务
final long timeInterval = 1000;
int count = 1;
Runnable runnable = new Runnable() {
public void run() {
System.out.println("thread start");
while (true) {
// ------- code for task to run
modifiedFlag = (ReadTxt.readFile(this.getClass().getResource("").getPath() + "Modified.ini")).get(0)
.equals("1");
if (modifiedFlag) {
refreshTree();
ReadTxt.writeFile(this.getClass().getResource("").getPath() + "Modified.ini", "0"); // 刷新之后关闭刷新
} else {
if (count >= 10) { // 因为有时候文件夹改变的通知接收可能会收不到所以我们还设置即使未收到刷新通知我们还是每10个间隔刷新一下目录结构
refreshTree();
ReadTxt.writeFile(this.getClass().getResource("").getPath() + "Modified.ini", "0"); // 刷新之后关闭刷新
count = 0;
}
}
count = count + 1;
// ------- ends here
try {
Thread.sleep(timeInterval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread thread = new Thread(runnable);
public static IconNode traverseFolder(String path) {
// 将该路径下的文件夹及子文件夹做成树状节点的结构体根节点是parentNode叶子节点是子文件夹及子文件
// path是一个文件夹路径
IconNode parentNode = new IconNode(new File(path).getName());
File file = new File(path);
if (file.exists()) {
File[] files = file.listFiles();
if (files.length == 0) {
if (file.isDirectory()) { // 如果是空文件夹
IconNode dn = new IconNode(file.getName(), false);
dn.setFilePath(file.getAbsolutePath());
dn.setIcon(new ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/folder.png")));
return dn;
}
} else { // 如果是文件夹内含有文件/文件夹
parentNode.setIcon(new ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/folder.png")));
parentNode.setFilePath(path);
for (File file2 : files) {
if (file2.isDirectory()) {
// 是目录的话,生成节点,并添加里面的节点
IconNode childtraverseFolder = traverseFolder(file2.getAbsolutePath());
parentNode.add(childtraverseFolder);
childtraverseFolder
.setIcon(new ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/folder.png")));
childtraverseFolder.setFilePath(file2.getAbsolutePath());
} else {
// 是文件的话直接生成节点,并把该节点加到对应父节点上
String nodeName = file2.getName();
IconNode temp = new IconNode(nodeName);
temp.setFilePath(file2.getAbsolutePath());
parentNode.add(temp);
String nodeSuffixName = nodeName.substring(nodeName.lastIndexOf(".") + 1);
if (nodeSuffixName.equals("java")) {
temp.setIcon(
new ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/Agent_mini.png")));
} else if (nodeSuffixName.equals("pddl")) {
temp.setIcon(new ImageIcon(
AutoRobotCodeGenerator.class.getResource("/icon1/Planning Node_mini.png")));
} else if (nodeSuffixName.equals("python")) {
temp.setIcon(new ImageIcon(
AutoRobotCodeGenerator.class.getResource("/icon1/ROS Node_mini.png")));
} else if (nodeSuffixName.equals("arcgprj")) { // AutoRobot Code Generator Project
// 这里表示添加一个项目的drawlist保存文件
temp.setIcon(
new ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/arcgprj_mini.png")));
} else {
System.out.println(nodeSuffixName);
System.out.println("The type is not included yet.");
}
}
}
}
} else {// 文件不存在
return null;
}
return parentNode;
}
public void refreshTree() {
// 树状结构图构建刷新
Node = traverseFolder(curApplicationPath); // 构建树并返回根节点Node
newModel = new DefaultTreeModel(Node); // 根据根节点TreeModel构造出DefaultTreeModel
tree = new JTree(newModel);
tree.setCellRenderer(new IconNodeRenderer()); // 设置单元格描述
tree.setEditable(false); // 设置树是否可编辑
tree.setRootVisible(true);// 设置树的根节点是否可视
expandTree(tree); // 展开目录树
treejslp.setViewportView(tree);
// JTree单击响应事件
tree.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
}
public void mousePressed(MouseEvent e) {
JPopupMenu popMenu = null;
if (SwingUtilities.isRightMouseButton(e))
if (tree.getPathForLocation(e.getX(), e.getY()) != null) {
///// 下面是右键响应事件
// 添加菜单项以及为菜单项添加事件
popMenu = new JPopupMenu();
JMenuItem showClassDiagramItem = new JMenuItem("view class diagram");
popMenu.add(showClassDiagramItem);
popMenu.show(getContentPane(), e.getX() + 30, e.getY() + 30);
showClassDiagramItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
TreePath treepath = tree.getSelectionPath();
if (treepath != null) {
// 下面两行是取得被点击项的文件路径
IconNode selectionNode = (IconNode) treepath.getLastPathComponent();
MyGramJPanel class_diagram = new MyGramJPanel(selectionNode.getFilePath());
class_diagram.setLocationRelativeTo(AutoRobotCodeGenerator.this);
class_diagram.setVisible(true);
}
}
});
}
}
});
}
public static void expandTree(JTree tree) {
// 使得目录树展开
TreeNode root = (TreeNode) tree.getModel().getRoot();
expandAll(tree, new TreePath(root), true);
}
private static void expandAll(JTree tree, TreePath parent, boolean expand) {
// Traverse children
TreeNode node = (TreeNode) parent.getLastPathComponent();
if (node.getChildCount() >= 0) {
for (Enumeration e = node.children(); e.hasMoreElements();) {
TreeNode n = (TreeNode) e.nextElement();
TreePath path = parent.pathByAddingChild(n);
expandAll(tree, path, expand);
}
}
// Expansion or collapse must be done bottom-up
if (expand) {
tree.expandPath(parent);
} else {
tree.collapsePath(parent);
}
}
private void creatApplicationMethod() {
if (newDialog == null)
newDialog = new NewApplication();
if (newDialog.showDialog(AutoRobotCodeGenerator.this, "Create Application")) {
curApplicationPath = newDialog.newApplicationPath() + '/' + newDialog.newApplicationName();
File newApplicationContent = new File(curApplicationPath);
Boolean newSucceed = newApplicationContent.mkdirs();
if (newSucceed) {
(new File(curApplicationPath + '/' + "Agent")).mkdirs();
(new File(curApplicationPath + '/' + "PDDL Files")).mkdirs();
(new File(curApplicationPath + '/' + "Ros Nodes")).mkdirs();
}
// 创建配置文件
AgentConfigurationCodeGeneratorClient.AgentFileGenerator(curApplicationPath);
writeApplicationPath();
refreshTree();
reloadPanelMethod();
}
}
private void writeApplicationPath() {
System.out.println("writeFile");
ReadTxt.writeFile(this.getClass().getResource("").getPath() + "userApplicationPath.ini", curApplicationPath);
}
private void openApplicationMethod() {
openDialog = new OpenApplication();
if (openDialog.showDialog(AutoRobotCodeGenerator.this, "Open Application")) {
curApplicationPath = openDialog.openApplicationPath();
refreshTree();
// 类图构建刷新
/*
* GramJPanell gjp = new GramJPanell (curApplicationPath); JScrollPane jslp =
* new JScrollPane (gjp); tabbedPane.setComponentAt(0, jslp); // 第0个选项卡内容设为jslp
*/
GramJPanell gjp = new GramJPanell(curApplicationPath);
JScrollPane jslp = new JScrollPane(gjp);
tabbedPane.setComponentAt(0, jslp); // 第0个选项卡内容设为jslp
writeApplicationPath();
reloadPanelMethod();
}
}
private void reloadPanelMethod() {
// 和画板内部路径统一
DesinModelPanel.mypath = curApplicationPath;
// 打开画板文件
String pannelPath = (curApplicationPath + "/.arcgprj");
File file = new File(pannelPath);
if (file.exists()) {
DesinModelPanel.cans.setDrawlist(MyCanvas.readDrawList(pannelPath));
DesinModelPanel.cans.repaint();
} else {
System.out.println("No canvas file in this project.");
}
// 开启定时刷新
if (!thread.isAlive()) {
thread.start();
}
}
}

@ -0,0 +1,158 @@
package CodeGenerator;
import jade.core.FrontEnd;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import sun.security.util.Length;
public class ChooseRelationJFrame extends JFrame implements ActionListener {
private JButton setRelationButton;
private DrawElement drawelement;
private MyCanvas cans;
private JComboBox <String> comboBoxRelationType;
private List<String> optionalRelation;
private int optionalRelationLength;
private String mypath;
public ChooseRelationJFrame(String mypath, DrawElement drawelement, MyCanvas cans) {
super("Setting Relation");
this.drawelement = drawelement;
this.cans = cans;
this.mypath = mypath;
this.setLayout(null);
this.optionalRelation = ReadTxt.readFile(this .getClass().getResource( "" ).getPath() + "relation.ini"); // 包路径加上文件路径,文件中存储的是可选的关系
this.setBounds(300, 300, 450, 140);
MyCanvas tempCans = cans; // 必须创建这两个局部变量才能在下面的windowClosing事件中访问到
DrawElement tempDrawElement = drawelement;
this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); // 捕捉关闭窗口事件
this.addWindowListener(new WindowAdapter() { // 捕捉到窗口关闭事件
public void windowClosing(WindowEvent e) {
/*
*code for example:
int i=JOptionPane.showConfirmDialog(null, "确定要退出系统吗?", "退出系统", JOptionPane.YES_NO_OPTION);
if(i==JOptionPane.YES_OPTION){
System.exit(0);
}
*/
// 如果未按下选择关系的按钮退出,而是选择按右上角的关闭对话框按钮,会触发该事件
// 触发该事件后我们要将之前已经添加到drawlist中的templist删除
tempCans.removeIcon(tempDrawElement);
dispose();
}
});
JLabel lblCreatingRelation = new JLabel("Choose a relation:");
lblCreatingRelation.setBounds(60, 24, 134, 16);
this.add(lblCreatingRelation);
comboBoxRelationType = new JComboBox();
comboBoxRelationType.setBounds(206, 19, 217, 27);
this.add(comboBoxRelationType);
for (int i = 0; i < optionalRelation.size(); i++) {
comboBoxRelationType.addItem(optionalRelation.get(i));
}
setRelationButton = new JButton("Set relation");
//createAgentButton.setBounds(177, 130, 117, 29);
setRelationButton.setBounds(260, 59, 163, 29);
this.add(setRelationButton);
setRelationButton.addActionListener(this);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO 自动生成的方法存根
if(e.getSource() == this.setRelationButton) {
String relationType = (String)this.comboBoxRelationType.getSelectedItem();
if(relationType!=null&&!relationType.equals("")) {
drawelement.setName(relationType);
}
MyCanvas.saveDrawList(this.mypath +"/.arcgprj", this.cans.getDrawlist());
cans.repaint();
// 选择关系之后要根据箭头,插入箭头相关的代码
DrawElement beginele = drawelement.getDrawlist().get(0);
DrawElement endele = drawelement.getDrawlist().get(1);
String end1 = beginele.getFilename().substring(beginele.getFilename().lastIndexOf(".")+1);
String end2 = endele.getFilename().substring(endele.getFilename().lastIndexOf(".")+1);
if(end1.equals("java")&&end2.equals("java")) {
// 箭头会导致beginele对应的java文件代码重新生成
if(beginele.getSpecificType().equals("taskPlanningAgent")){
PlannerAgentCodeGeneratorClient.AgentFileGenerator(mypath, beginele, cans);
}else if (beginele.getSpecificType().equals("dispatchAgent")) {
DispatcherAgentCodeGeneratorClient.AgentFileGenerator(mypath, beginele, cans);
}else if (beginele.getSpecificType().equals("moveAgent")) {
ActuatorAgentCodeGeneratorClient.AgentFileGenerator(mypath, beginele, cans);
}else {
System.out.print("No beginele SpecificType meet the condition. ");
System.out.println(beginele.getSpecificType());
}
// 箭头会导致endele对应的java文件代码重新生成
if(endele.getSpecificType().equals("taskPlanningAgent")){
PlannerAgentCodeGeneratorClient.AgentFileGenerator(mypath, endele, cans);
}else if (endele.getSpecificType().equals("dispatchAgent")) {
DispatcherAgentCodeGeneratorClient.AgentFileGenerator(mypath, endele, cans);
}else if (endele.getSpecificType().equals("moveAgent")) {
ActuatorAgentCodeGeneratorClient.AgentFileGenerator(mypath, endele, cans);
}else {
System.out.print("No endele SpecificType meet the condition. ");
System.out.println(endele.getSpecificType());
}
}
if(end1.equals("java")&&end2.equals("python")) {
/*
//String strcount = JOptionPane.showInputDialog(this,"请输入插入java文件的行数(默认末尾)");
int strcount = 20;
int linecount1 = Integer.MAX_VALUE-1;
try {
//linecount1 = Integer.parseInt(strcount);
linecount1 = strcount;
}catch(Exception e1){}
FileUtils.Write(beginele.getFilename(), "SendDataToROSBehaviour("+endele.getName()+")",linecount1);
*/
System.out.println("Java to Python");
}
if(end1.equals("python")&&end2.equals("java")) {
/*
//String strcount = JOptionPane.showInputDialog(this,"请输入插入java文件的行数(默认末尾)");
int strcount = 20;
int linecount1 = Integer.MAX_VALUE-1;
try {
//linecount1 = Integer.parseInt(strcount);
linecount1 = strcount;
}catch(Exception e1){}
FileUtils.Write(endele.getFilename(), "ReceiveDataFromROSBehaviour("+beginele.getName()+")",linecount1);
*/
System.out.println("Python to Java");
}
this.dispose(); // 销毁选择对话框
}
}
}

@ -0,0 +1,46 @@
package CodeGenerator;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
public class Clazzs {
//POJO类描述一个类的UML图
private String name = "";
private File file = null;
private List<String> fields = new LinkedList();
private List<String> methods = new LinkedList();
private String parentClassName = "";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public List<String> getFields() {
return fields;
}
public void setFields(List<String> fields) {
this.fields = fields;
}
public List<String> getMethods() {
return methods;
}
public void setMethods(List<String> methods) {
this.methods = methods;
}
public String getParentClassName() {
return this.parentClassName;
}
public void setParentClassName(String parentClassName) {
this.parentClassName = parentClassName;
}
}

@ -0,0 +1,74 @@
package CodeGenerator;
import java.awt.Color;
import java.awt.GridLayout;
import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import com.sun.javafx.application.PlatformImpl;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.web.WebView;
public class CodeEditor extends JFrame{
JButton button = new JButton("a");
public CodeEditor() {
super();
this.setName("b");
this.setSize(800,500);
this.setLocationRelativeTo(null);
this.setLayout(new GridLayout(1,1));
/*JFileChooser fd = new JFileChooser();
fd.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fd.showOpenDialog(null);
File f = fd.getSelectedFile();
if(f != null){*/
/*
File file = new File("/Users/mac/Desktop/autorobot2.0/autorobot2.0/AutoRobot-master/src/agent/");
this.add(new JScrollPane(new GramJPanel(file.getAbsolutePath())));
*/
JFXPanel fxPanel = new JFXPanel ();
PlatformImpl.runLater ( new Runnable () {
@Override
public void run () {
WebView webView = new WebView ();
//webView.getEngine().loadContent("<html> Hello World!");
//webView.getEngine ().load ( "file:///Users/mac/Desktop/test.html" );
webView.getEngine().load("file:////Users/mac/Desktop/test.html");
fxPanel.setScene ( new Scene ( webView ) );
}
});
JScrollPane jslp = new JScrollPane(fxPanel);
jslp.setBounds(254, 26, 544, 525);
this.add(jslp);
jslp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
jslp.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
//this.add(new JScrollPane(fxPanel));
//}
this.setVisible(true);
this.setDefaultCloseOperation(HIDE_ON_CLOSE);
//this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
//this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
}
// public static void main(String args[]) {
// CodeEditor t = new CodeEditor();
// }
}

@ -0,0 +1,61 @@
package CodeGenerator;
import java.util.List;
/**
*
* @author lvzb.software@qq.com
*
*/
public class ControllerEntity {
// 实体所在的包名
private String javaPackage;
// 实体类名
private String className;
// 父类名
private String superclass;
//属性方法controller集合
List<ControllerEntity> controllerentities;
// 是否有构造函数
private boolean constructors;
public String getJavaPackage() {
return javaPackage;
}
public void setJavaPackage(String javaPackage) {
this.javaPackage = javaPackage;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getSuperclass() {
return superclass;
}
public void setSuperclass(String superclass) {
this.superclass = superclass;
}
public List<ControllerEntity> getControllerentities(){
return controllerentities;
}
public void setControllerentities(List<ControllerEntity> controllerentities) {
this.controllerentities = controllerentities;
}
public boolean isConstructors() {
return constructors;
}
public void setConstructors(boolean constructors) {
this.constructors = constructors;
}
}

@ -0,0 +1,118 @@
package CodeGenerator;
import java.io.File;
/**
*
*
*/
public class DeleteFileUtil {
/**
*
*
* @param fileName
*
* @return truefalse
*/
public static boolean delete(String fileName) {
File file = new File(fileName);
if (!file.exists()) {
System.out.println("删除文件失败:" + fileName + "不存在!");
return false;
} else {
if (file.isFile())
return deleteFile(fileName);
else
return deleteDirectory(fileName);
}
}
/**
*
*
* @param fileName
*
* @return truefalse
*/
public static boolean deleteFile(String fileName) {
File file = new File(fileName);
// 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
if (file.exists() && file.isFile()) {
if (file.delete()) {
System.out.println("删除单个文件" + fileName + "成功!");
return true;
} else {
System.out.println("删除单个文件" + fileName + "失败!");
return false;
}
} else {
System.out.println("删除单个文件失败:" + fileName + "不存在!");
return false;
}
}
/**
*
*
* @param dir
*
* @return truefalse
*/
public static boolean deleteDirectory(String dir) {
// 如果dir不以文件分隔符结尾自动添加文件分隔符
if (!dir.endsWith(File.separator))
dir = dir + File.separator;
File dirFile = new File(dir);
// 如果dir对应的文件不存在或者不是一个目录则退出
if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
System.out.println("删除目录失败:" + dir + "不存在!");
return false;
}
boolean flag = true;
// 删除文件夹中的所有文件包括子目录
File[] files = dirFile.listFiles();
for (int i = 0; i < files.length; i++) {
// 删除子文件
if (files[i].isFile()) {
flag = DeleteFileUtil.deleteFile(files[i].getAbsolutePath());
if (!flag)
break;
}
// 删除子目录
else if (files[i].isDirectory()) {
flag = DeleteFileUtil.deleteDirectory(files[i]
.getAbsolutePath());
if (!flag)
break;
}
}
if (!flag) {
System.out.println("删除目录失败!");
return false;
}
// 删除当前目录
if (dirFile.delete()) {
System.out.println("删除目录" + dir + "成功!");
return true;
} else {
return false;
}
}
public static void main(String[] args) {
// // 删除单个文件
// String file = "c:/test/test.txt";
// DeleteFileUtil.deleteFile(file);
// System.out.println();
// 删除一个目录
String dir = "D:/home/web/upload/upload/files";
DeleteFileUtil.deleteDirectory(dir);
// System.out.println();
// // 删除文件
// dir = "c:/test/test0";
// DeleteFileUtil.delete(dir);
}
}

@ -0,0 +1,42 @@
package SampleApplication.Agent;
import SampleApplication.AgentConfiguration;
import agentBehaviourPrototype.ExecutionBehaviour;
import agentBehaviourPrototype.ReceiveDataFromAgentBehaviour;
import agentBehaviourPrototype.SendDataToAgentBehaviour;
import agentEntityPrototype.RobotAgent;
import edu.wpi.rail.jrosbridge.services.std.Empty.Request;
import jade.core.AID;
public class ${entity.className}<#if entity.superclass?has_content> extends ${entity.superclass} </#if>
{
Request parseRequest = new Request();
Request dispatchRequest = new Request();
<#list entity.allRelatedElements as allReEle>
private AID ${allReEle.specificType} = new AID(AgentConfiguration.${allReEle.specificType}ID, false);
</#list>
protected void setup() {
this.controller.addService(AgentConfiguration.parseServiceName, AgentConfiguration.parseServiceType);
this.controller.addService(AgentConfiguration.dispatchServiceName, AgentConfiguration.dispatchServiceType);
this.controller.getService(AgentConfiguration.parseServiceName).callServiceAndWait(parseRequest);
this.controller.getService(AgentConfiguration.dispatchServiceName).callServiceAndWait(dispatchRequest);
//agent communication
<#list entity.postiveRelatedElementsWithRelation as posReEleWithRela>
this.behList.addElement(new SendDataToAgentBehaviour(this, controller, ${posReEleWithRela.specificType}, AgentConfiguration.${posReEleWithRela.relation}DataKey));
</#list>
<#list entity.negativeRelatedElementsWithRelation as negReEleWithRela>
this.behList.addElement(new ReceiveDataFromAgentBehaviour(this, controller, ${negReEleWithRela.specificType}, AgentConfiguration.${negReEleWithRela.relation}DataKey));
</#list>
addBehaviour(tbf.wrap(new ExecutionBehaviour(this, ds, this.behList)));
}
}

@ -0,0 +1,192 @@
package CodeGenerator;
import java.awt.Canvas;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class DispatcherAgentCodeGeneratorClient {
private static File javaFile = null;
public static void AgentFileGenerator(String path, DrawElement drawelement, MyCanvas cans) {
Configuration cfg = new Configuration();
try {
// 指定模板文件从何处加载的数据源,这里设置一个文件目录
cfg.setDirectoryForTemplateLoading(new File("./src/CodeGenerator"));
cfg.setObjectWrapper(new DefaultObjectWrapper());
// 获取模板文件
Template template = cfg.getTemplate("DispatcherAgent.ftl");
// 创建数据模型
Map<String, Object> root = createDataModel(path, drawelement, cans);
// 合并模板和数据模型
// 创建.java类文件
if(javaFile != null){
Writer javaWriter = new FileWriter(javaFile);
template.process(root, javaWriter);
javaWriter.flush();
System.out.println("文件生成路径:" + javaFile.getCanonicalPath());
javaWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
}
//创建数据模型
private static Map<String, Object> createDataModel(String path, DrawElement drawelement, MyCanvas cans) {
Map<String, Object> root = new HashMap<String, Object>();
Entity user = new Entity();
TbfEntity user1 = new TbfEntity();
ControllerEntity user2 = new ControllerEntity();
//user.setJavaPackage("agent"); // 创建包名
user.setClassName(drawelement.getName()); // 创建类名
user.setConstructors(false); // 是否创建构造函数
user.setSuperclass("RobotAgent");//创建父类
user.setSpecificType(drawelement.getSpecificType());
List<Property> propertyList = new ArrayList<Property>();
List<TbfEntity> tbfEntityList = new ArrayList<TbfEntity>();
List<Entity> entityList = new ArrayList<Entity>();
List<ControllerEntity> controllerEntityList = new ArrayList<ControllerEntity>();
List<DrawElementWithRelation> postiveRelatedElementsWithRelation = new ArrayList<DrawElementWithRelation>();
List<DrawElementWithRelation> negativeRelatedElementsWithRelation = new ArrayList<DrawElementWithRelation>();
List<DrawElement> allRelatedElements = new ArrayList<DrawElement>();
// 创建实体属性
Property attribute1 = new Property();
attribute1.setJavaType("static final long");
attribute1.setPropertyName("serialVersionUID");
attribute1.setPropertyType(PropertyType.Long);
// 创建实体属性(tbf)
int tbfAmount = 4; //这里输入tbf的数量
for (int i = 1; i < tbfAmount +1 ; i = i + 1) {
String tbfName = "tbf" + i;
TbfEntity tbfEntityAttribute = new TbfEntity();
tbfEntityAttribute.setClassName(tbfName);
tbfEntityAttribute.setSuperclass("ThreadedBehaviourFactory");
tbfEntityList.add(tbfEntityAttribute);
}
//TbfEntity tbfEntityAttribute2 = new TbfEntity();
//tbfEntityAttribute2.setClassName("tbf2");
//tbfEntityAttribute2.setSuperclass("ThreadedBehaviourFactory");
//创建实体属性(controller)
ControllerEntity controllerAttribute = new ControllerEntity();
controllerAttribute.setClassName("moveController");
controllerAttribute.setSuperclass("Controller");
//创建实体属性(除tbf和controller以外的属性)
Entity entityAttribute1 = new Entity();
entityAttribute1.setClassName("cameraAgent");
entityAttribute1.setSuperclass("AID");
Entity entityAttribute2 = new Entity();
entityAttribute2.setClassName("bumperAgent");
entityAttribute2.setSuperclass("AID");
Entity entityAttribute3 = new Entity();
entityAttribute3.setClassName("ds");
entityAttribute3.setSuperclass("DataStore");
propertyList.add(attribute1);
//tbfEntityList.add(tbfEntityAttribute1);
//tbfEntityList.add(tbfEntityAttribute2);
controllerEntityList.add(controllerAttribute);
entityList.add(entityAttribute1);
entityList.add(entityAttribute2);
entityList.add(entityAttribute3);
// 判断该元素是否和其他元素有箭头关系
for(DrawElement drawEleInDrawlist:cans.getDrawlist()) {
if(drawEleInDrawlist.getType() == 2){ // 是箭头线段的时候要判断是否和该元素有关
if (drawelement.getName() == drawEleInDrawlist.getDrawlist().get(0).getName()){ // 该元素是箭头线段的起始点
allRelatedElements.add(drawEleInDrawlist.getDrawlist().get(1)); //列表中存储的是箭头线段的结束点
postiveRelatedElementsWithRelation.add(new DrawElementWithRelation(drawEleInDrawlist.getDrawlist().get(1), drawEleInDrawlist.getName()));
}
else if (drawelement.getName() == drawEleInDrawlist.getDrawlist().get(1).getName()) { // 该元素是箭头线段的结束点
allRelatedElements.add(drawEleInDrawlist.getDrawlist().get(0));
negativeRelatedElementsWithRelation.add(new DrawElementWithRelation(drawEleInDrawlist.getDrawlist().get(0), drawEleInDrawlist.getName()));
}
else{}
}
}
// 将有关系的对象放到同一个列表中但不能重复为了后续生成的文件中获取交互对象id的那一行用
removeDuplicate(allRelatedElements);
// 将属性集合添加到实体对象中
user.setProperties(propertyList);
user.setEntities(entityList);
user.setPostiveRelatedElementsWithRelation(postiveRelatedElementsWithRelation); // 箭头线段的起始点在该对象
user.setNegativeRelatedElementsWithRelation(negativeRelatedElementsWithRelation); // 箭头线段的结束点在该对象
user.setAllRelatedElements(allRelatedElements); // 和该对象用箭头相关的所有对象都在该列表中
user1.setTbfentities(tbfEntityList);
user2.setControllerentities(controllerEntityList);
// 创建.java类文件
File outDirFile = new File(path + "/Agent"); // .java类文件存放的文件夹
if(!outDirFile.exists()){
outDirFile.mkdir();
}
javaFile = toJavaFilename(outDirFile, user.getClassName());
root.put("entity", user);
root.put("tbfentity",user1);
root.put("controllerentity", user2);
return root;
}
/**
* .java .javaFile
* @param outDirFile
* @param javaPackage java
* @param javaClassName java
* @return
*/
private static File toJavaFilename(File outDirFile, String javaClassName) {
File file = new File(outDirFile, javaClassName + ".java");
return file;
}
// 删除ArrayList中重复元素
public static void removeDuplicate(List<DrawElement> list) {
for (int i = 0; i < list.size() - 1; i++) {
for (int j = list.size() - 1; j > i; j--) {
if (list.get(j).equals(list.get(i))) {
list.remove(j);
}
}
}
}
}

@ -0,0 +1,18 @@
(define (${entity.className})
(:requirements )
(:types
)
(:predicates
)
(:durative-action goto_waypoint
:parameters
:duration
:condition
:effect
)

@ -0,0 +1,110 @@
package CodeGenerator;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class DomainDescriptionGeneratorClient {
private static File pddlFile = null;
public static void PDDLFileGenerator(String path, String pddlName) {
Configuration cfg = new Configuration();
try {
// 指定模板文件从何处加载的数据源,这里设置一个文件目录
cfg.setDirectoryForTemplateLoading(new File("./src/CodeGenerator"));
cfg.setObjectWrapper(new DefaultObjectWrapper());
// 获取模板文件
Template template = cfg.getTemplate("DomainDescription.ftl");
// 创建数据模型
Map<String, Object> root = createDataModel(path, pddlName);
// 合并模板和数据模型
// 创建.pddl类文件
if(pddlFile != null){
Writer pddlWriter = new FileWriter(pddlFile);
template.process(root, pddlWriter);
pddlWriter.flush();
System.out.println("文件生成路径:" + pddlFile.getCanonicalPath());
pddlWriter.close();
}
// 输出到Console控制台
/*
Writer out = new OutputStreamWriter(System.out);
template.process(root, out);
out.flush();
out.close();
*/
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
}
//创建数据模型
private static Map<String, Object> createDataModel(String path, String pddlName) {
Map<String, Object> root = new HashMap<String, Object>();
Entity user = new Entity();
//TbfEntity user1 = new TbfEntity();
//ControllerEntity user2 = new ControllerEntity();
//user.setJavaPackage("agent"); // 创建包名
user.setClassName(pddlName); // 创建类名
user.setConstructors(false); // 是否创建构造函数
//user.setSuperclass("Agent");//创建父类
List<Property> propertyList = new ArrayList<Property>();
List<Entity> entityList = new ArrayList<Entity>();
// 创建实体属性
Property attribute1 = new Property();
attribute1.setJavaType("static final long");
attribute1.setPropertyName("serialVersionUID");
attribute1.setPropertyType(PropertyType.Long);
// 将属性集合添加到实体对象中
user.setProperties(propertyList);
user.setEntities(entityList);
// 创建.pddl类文件
File outDirFile = new File(path + "/PDDL Files");
if(!outDirFile.exists()){
outDirFile.mkdir();
}
//javaFile = toJavaFilename(outDirFile, user.getJavaPackage(), user.getClassName());
pddlFile = toPddlFilename(outDirFile, user.getClassName());
root.put("entity", user);
return root;
}
/**
* .pddl .pddlFile
* @param outDirFile
* @param javaPackage java
* @param javaClassName java
* @return
*/
private static File toPddlFilename(File outDirFile, String pddlName) {
File file = new File(outDirFile, pddlName + ".pddl");
return file;
}
}

@ -0,0 +1,78 @@
package CodeGenerator;
import java.awt.Point;
import java.util.ArrayList;
//表示一个图形或一条有向线段
public class DrawElement {
private String name; // 是图标的时候表示图标名称,是线段的时候表示线段的关系类型
private String path; // 图标路径
private String filename; // 对应文件地址,相对路径
private Point p1; // 图标在画布上的位置
private ArrayList<DrawElement> drawlist=null; // 是直线的时候才会用到这个变量,存放着直线的起始点和结束点
private int type=1;//type=1为图案type=2为线条
private String specificType; // 需要设置此项因为在写入箭头的时候需要知道Agent具体是哪种类型的
public DrawElement(String name, String path, Point p1,String filename) {
super();
this.name = name;
this.path = path;
this.p1 = p1;
this.filename = filename;
}
public DrawElement(DrawElement beginele,DrawElement endele) {
this(null,null,new Point(-1,-1),null); // 线条元素的信息起始点信息由drawlist保存关系名称由name保存
this.drawlist = new ArrayList<DrawElement>();
drawlist.add(beginele);
drawlist.add(endele);
this.type=2;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public Point getP1() {
return p1;
}
public void setP1(Point p1) {
this.p1 = p1;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getSpecificType() {
return specificType;
}
public void setSpecificType(String specificType) {
this.specificType = specificType;
}
public ArrayList<DrawElement> getDrawlist() {
return drawlist;
}
public void setDrawlist(ArrayList<DrawElement> drawlist) {
this.drawlist = drawlist;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
}

@ -0,0 +1,62 @@
package CodeGenerator;
import java.awt.Point;
public class DrawElementWithRelation extends DrawElement{
// 该类中包含一个图案对象和一个关系。在生成ftl文件时我们需要存储一个对象和其他对象的关系就将一个对象和对应的关系存储在一起最后将这样的数据结构存为list在生成ftl文件的时候有用
private String name;
private String path;
private Point p1;
private String filename;
private String relation;
private String specificType;
private int arrowDirection;
private DrawElement relationDrawElement;
public DrawElementWithRelation(DrawElement drawElement, String relation) {
super(drawElement.getName(), drawElement.getPath(), drawElement.getP1(), drawElement.getFilename());
this.specificType = drawElement.getSpecificType();
this.relation = relation;
this.arrowDirection = 2; // 存储箭头指向默认不是0和1就行1表示箭头是由鼠标右键的图案为起始点的
}
public DrawElementWithRelation(DrawElement drawElement, DrawElement relationDrawElement, int arrowDirection) { // drawElement表示箭头的另一端的图案对象relationDrawElement表示箭头线段对象
super(drawElement.getName(), drawElement.getPath(), drawElement.getP1(), drawElement.getFilename());
this.specificType = drawElement.getSpecificType();
this.relationDrawElement = relationDrawElement;
this.arrowDirection = arrowDirection; // 存储箭头指向0表示箭头线段是由鼠标右键的图案为起始点的1表示箭头线段是由鼠标右键的图案为结束点的
this.relation = relationDrawElement.getName();
}
public void setRelation(String relation) {
this.relation = relation;
}
public String getRelation() {
return relation;
}
public String getSpecificType() { // specificType属性不是继承过来的需要自己写set和get方法
return specificType;
}
public void setSpecificType(String specificType) {
this.specificType = specificType;
}
public void setArrowDirection(int arrowDirection) {
this.arrowDirection = arrowDirection;
}
public int getArrowDirection() {
return arrowDirection;
}
public DrawElement getRelationDrawElement() {
return relationDrawElement;
}
public void setRelationDrawElement(DrawElement relationDrawElement) {
this.relationDrawElement = relationDrawElement;
}
}

@ -0,0 +1,461 @@
package CodeGenerator;
import java.awt.BorderLayout;
import java.awt.CheckboxMenuItem;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Menu;
import java.awt.Point;
import java.awt.PopupMenu;
import java.awt.SystemColor;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;
import javax.swing.border.BevelBorder;
import javax.swing.border.SoftBevelBorder;
import com.sun.org.apache.xalan.internal.xsltc.compiler.Template;
import edu.wpi.rail.jrosbridge.messages.std.Time;
public class DrawJPanel extends JPanel implements ActionListener, MouseMotionListener, MouseListener{
MyCanvas cans;
JButton buttons[];
JButton paintButton = null;
DrawElement beginele,endele;
int flag = 0;//flag = 0不做图=1绘制图形=2绘制直线
int xx=0,yy=0;//鼠标按下位置
int size = 47;
DrawElement presselement = null;
String mypath;
// 构造方法
DrawJPanel(String str) {
this.mypath = str;
this.setLayout(new BorderLayout());
JPanel toolpanel = this.createToolPanel();
cans = new MyCanvas();
cans.setBackground(Color.white);
cans.addMouseMotionListener(this); // 提供移动和拖动鼠标的监听
cans.addMouseListener(this);
this.add(new JScrollPane(cans));
this.add(toolpanel,BorderLayout.WEST);
}
//创建工具栏
private JPanel createToolPanel() {
JPanel panel = new JPanel(new BorderLayout());
//panel.setBackground(new Color(108,218,180));
panel.setBackground(SystemColor.window);
JToolBar toolBar = new JToolBar();
toolBar.setOrientation(JToolBar.VERTICAL);
toolBar.setOpaque(false);
toolBar.setFloatable(false);//工具栏不可移动
toolBar.setBorder(new SoftBevelBorder(BevelBorder.RAISED, null, null, null, null));
toolBar.setMargin(new Insets(2, 2, 200, 2));//设置工具栏边框
String names[] = {"Agent","Planning Node","ROS Node","Connection"};
toolBar.setLayout(new GridLayout(names.length+1, 1));
buttons = new JButton[names.length];
for (int i = 0;i<names.length;i++) {
//ImageIcon action = new ImageIcon("img//"+names[i]+".png");
ImageIcon action = new ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/" + names[i] + "_small.png"));
//action.setImage(action.getImage().getScaledInstance(35, 35, 0));
buttons[i] = new JButton();
toolBar.add(buttons[i]);
buttons[i].setVerticalTextPosition(SwingConstants.BOTTOM);
buttons[i].setHorizontalTextPosition(SwingConstants.CENTER);
buttons[i].setIcon(action);
buttons[i].setText(names[i]);
buttons[i].setOpaque(false);
buttons[i].setBorder(null);
}
buttons[0].addMouseListener(this);
buttons[1].addMouseListener(this);
buttons[2].addMouseListener(this);
buttons[3].addActionListener(this);
JButton tempbutton = new JButton("Design Palette");
tempbutton.addActionListener(this);
tempbutton.setBorder(BorderFactory.createEtchedBorder());
tempbutton.setBackground(new Color(108,218,180));
tempbutton.setOpaque(true);
//tempbutton.setBorderPainted(false);
panel.add(tempbutton,"North");
panel.add(toolBar);
return panel;
}
public void clearCancas() {
this.cans.setDrawlist(new ArrayList<DrawElement>());
this.cans.repaint();
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == buttons[3]) {
flag = 2;
this.paintButton = null;
this.presselement = null;
beginele = null;
endele = null;
}
if(e.getActionCommand().equals("Design Palette")) {
//this.clearCancas();
String a =(ReadTxt.readFile(this.getClass().getResource("").getPath() + "userApplicationPath.ini")).get(0);
System.out.println(a);
}
}
@Override
public void mouseDragged(MouseEvent e) // 在画布中拖动鼠标时会调用
{}
@Override
public void mouseEntered(MouseEvent e)
{}
@Override
public void mouseExited(MouseEvent e)
{}
@Override
public void mouseMoved(MouseEvent e) { // 在画布中移动鼠标会调用
//System.out.println("mouseMoved");
// 点击连线按钮后会将flag赋值为2表示进入连线状态
// 连线状态下,鼠标移动到某图案附近,就会改变鼠标的样式,方便下一步的为了确定连线关系的图案点击操作
if(flag == 2) {
if(e.getSource() instanceof MyCanvas) {
xx = e.getX();
yy = e.getY();
boolean isIcon = false;
for(DrawElement drawelement:cans.getDrawlist()) {
if(xx>drawelement.getP1().getX()&&xx<(drawelement.getP1().getX()+size)
&&yy>drawelement.getP1().getY()&&yy<(drawelement.getP1().getY()+size)) {
Cursor coursor = Toolkit.getDefaultToolkit().createCustomCursor(new ImageIcon(drawelement.getPath()).getImage(),new Point(10,20), "stick");
this.setCursor(coursor);
this.presselement = drawelement;
isIcon = true;
break;
}
}
if(!isIcon) {
//this.setCursor(null);
if(beginele == null) {
Cursor coursor = Toolkit.getDefaultToolkit().createCustomCursor(new ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/first_small.png")).getImage(),new Point(10,20), "stick");
this.setCursor(coursor);
}else if(endele == null){
Cursor coursor = Toolkit.getDefaultToolkit().createCustomCursor(new ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/second_small.png")).getImage(),new Point(10,20), "stick");
this.setCursor(coursor);
}else{
this.setCursor(null);
}
}
}
}
}
@Override
public void mousePressed(MouseEvent e) { // 只有在鼠标按下在前三个按钮和画布的时候会发生(最后一个按钮没有添加鼠标监听)
//System.out.println("mousePressed");
if((e.getSource() instanceof JButton)&&(e.getButton() == MouseEvent.BUTTON1)) { // 按压到了工具栏的三个按钮其中一个
this.beginele = null; // 线段的起始点和结束点对象赋值为空
this.endele = null;
this.paintButton = (JButton) e.getSource();
Cursor coursor = Toolkit.getDefaultToolkit().createCustomCursor(new ImageIcon(AutoRobotCodeGenerator.class.getResource("/icon1/"+paintButton.getText()+".png")).getImage(),new Point(10,20), "stick");
this.setCursor(coursor); // 改变鼠标样式
this.flag = 1; // 表示下一步画图案
}
if((e.getSource() instanceof MyCanvas)&&(e.getButton() == MouseEvent.BUTTON1)) { // 判断是否在画布上按压到了图案
xx = e.getX(); // 按压时的坐标
yy = e.getY();
for(DrawElement drawelement:cans.getDrawlist()) {
if(xx>drawelement.getP1().getX()&&xx<(drawelement.getP1().getX()+size)
&&yy>drawelement.getP1().getY()&&yy<(drawelement.getP1().getY()+size)) {
Cursor coursor = Toolkit.getDefaultToolkit().createCustomCursor(new ImageIcon(drawelement.getPath()).getImage(),new Point(10,20), "stick");
this.setCursor(coursor); // 改变鼠标样式为图案的图标
this.presselement = drawelement; // 将按下的图案对象引用保存到presselement方便在其他行为中取用
}
}
}
}
@Override
public void mouseReleased(MouseEvent e) { // 在mousePressed发生后然后鼠标松开的时候就会有mouseReleased。前提是mousePressed发生mouseReleased一定发生
//System.out.println("mouseReleased");
this.setCursor(null);
if((e.getSource() instanceof MyCanvas && this.presselement!=null) && (e.getButton() == MouseEvent.BUTTON1)) { // 鼠标在画布上松开且按压到了图案,表示要移动图案
if(Math.abs(xx-e.getX())<10&&Math.abs(yy-e.getY())<10) { // 移动幅度过小
return;
}
this.presselement.setP1(new Point(e.getX()-size/2,e.getY()-size/2)); // e.getX()是鼠标左边减去size/2是要让图片显示在以鼠标指针为中心
MyCanvas.saveDrawList(this.mypath +"/.arcgprj", this.cans.getDrawlist());
this.presselement = null; // 按压拖动过程结束presselement赋值为空避免错误调用mouseReleased
cans.repaint(); // 由于有图案移动,需要重绘所有图案和有向线段
}
if(e.getX()>=90 && flag == 1 && (e.getButton() == MouseEvent.BUTTON1)) { // 按压按钮并拖动到画布上松开的情况
if(this.paintButton != null) {
String name = paintButton.getText(); // 之前按下的按钮名称
String path = "src/icon1/" + paintButton.getText() + ".png";
// 由于getX获取的相对坐标是相对于原按钮的所以每个按钮的相对坐标不一样分别处理
if(paintButton == buttons[0]) {
Point p = new Point(e.getX()-108,e.getY());
DrawElement drawelement = new DrawElement(name,path,p,"");
cans.addIcon(drawelement);
new JavaJFrame(this.mypath,drawelement,this.cans);
cans.repaint();
}
if(paintButton == buttons[1]) {
Point p = new Point(e.getX()-108,e.getY()+130);
DrawElement drawelement = new DrawElement(name,path,p,"");
cans.addIcon(drawelement);
new PddlJFrame(this.mypath,drawelement,this.cans);
cans.repaint();
}
if(paintButton == buttons[2]) {
Point p = new Point(e.getX()-108,e.getY()+268);
DrawElement drawelement = new DrawElement(name,path,p,"");
cans.addIcon(drawelement);
new PythonJFrame(this.mypath,drawelement,this.cans);
cans.repaint();
}
this.paintButton = null;
flag = 0;
}
}
if (flag == 1){// 如果不是在画布上松开的鼠标即有可能是在绘图工具栏松开的鼠标也要将flag设置为0
flag = 0;
}
}
@Override
public void mouseClicked(MouseEvent e) { // mousePressed发生了并且鼠标松开前没有移动就会在鼠标松开时触发该事件
if(e.getClickCount() == 2) { // 双击图案打开文件
for(DrawElement drawelement:cans.getDrawlist()) {
if(xx>drawelement.getP1().getX()&&xx<(drawelement.getP1().getX()+size)
&&yy>drawelement.getP1().getY()&&yy<(drawelement.getP1().getY()+size)) {
new EditorJFrame(this.mypath + drawelement.getFilename());
return;
}
}
}
int xx = e.getX(); // 鼠标单击的坐标
int yy = e.getY();
if(flag == 2) {//画连线(好像没有做重复直线的处理??)
DrawElement templist=null;
for(DrawElement drawelement:cans.getDrawlist()) {
if(xx>drawelement.getP1().getX()&&xx<(drawelement.getP1().getX()+size)
&&yy>drawelement.getP1().getY()&&yy<(drawelement.getP1().getY()+size)) { // 如果鼠标单击到了某个图案
if(beginele == null) {
beginele = drawelement;
}else if(endele == null && beginele != drawelement){
endele = drawelement;
templist = new DrawElement(beginele,endele);
templist.setName("");
new ChooseRelationJFrame(this.mypath, templist, this.cans); // 弹出选择关系对话框在其中完成templist.setName()操作templist中的两个起始元素和结束元素的源代码文件中都应当生成和箭头有关的代码
}
}
}
if(templist!=null) { // 因为cans.addIcon(templist)会修改cans.getDrawlist()造成上面的迭代失败所以必须要在外部进行判断再使用cans.addIcon(templist)
// 要注意这些代码虽然在ChooseRelationJFrame下方但是等到ChooseRelationJFrame窗口关闭的时候这些代码早就执行完了
flag = 0;
cans.addIcon(templist);
beginele = null;
endele = null;
}
}
if (e.getButton() == MouseEvent.BUTTON3) { // 鼠标右键单击
if(e.getSource() instanceof MyCanvas){ // 在画布上右键单击
xx = e.getX();
yy = e.getY();
DrawElement drawElementRightClicked = null;
for(DrawElement drawelement:cans.getDrawlist()) { // 找到被右击的图案drawElementRightClicked
if(xx>drawelement.getP1().getX()&&xx<(drawelement.getP1().getX()+size)
&&yy>drawelement.getP1().getY()&&yy<(drawelement.getP1().getY()+size)) {
drawElementRightClicked = drawelement;
break;
}
}
if (drawElementRightClicked != null) { // 鼠标在图案上右键了上面的代码中会对drawElementRightClicked赋值导致其非空
// 先找出和该图案有箭头关系的图案,保存下来图案名称及关系名称
ArrayList<DrawElementWithRelation> relatedElementsWithRelation = new ArrayList<DrawElementWithRelation>();
for(DrawElement drawEleInDrawlist:cans.getDrawlist()) {
if(drawEleInDrawlist.getType() == 2){ // 是箭头线段的时候要判断是否和该元素有关
if (drawElementRightClicked == drawEleInDrawlist.getDrawlist().get(0)){ // 该元素是箭头线段的起始点
// 将箭头结束点(即有关系的图案对象)和关系名称还有箭头指向放到一个列表中存储起来
relatedElementsWithRelation.add(new DrawElementWithRelation(drawEleInDrawlist.getDrawlist().get(1), drawEleInDrawlist, 1)); // 1表示由drawElementRightClicked指向另一个图案
}
else if (drawElementRightClicked == drawEleInDrawlist.getDrawlist().get(1)) { // 该元素是箭头线段的结束点
relatedElementsWithRelation.add(new DrawElementWithRelation(drawEleInDrawlist.getDrawlist().get(0), drawEleInDrawlist, 0));
}
else{}
}
}
createPopupMenu(this, xx+88, yy, drawElementRightClicked, relatedElementsWithRelation); // 创建右键菜单
}
}
}
}
private void createPopupMenu(DrawJPanel drawJPanel, int posX, int posY,
DrawElement drawElementRightClicked,
List<DrawElementWithRelation> relatedElementsWithRelation) {
// 参数鼠标右键点击时的X坐标和Y坐标被点击的图案指向的对象及关系名称列表被指向的对象及关系名称列表
//创建右键菜单
JPopupMenu pop = new JPopupMenu();
//创建菜单项组件
//-----------创建删除图案菜单项(同时会删除和对象的所有关系)--------------
JMenuItem deleteDrawElementItem = new JMenuItem("delete " + drawElementRightClicked.getName());
deleteDrawElementItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Object[] options ={ "Delete", "Cancel" }; //自定义按钮上的文字
int i=JOptionPane.showOptionDialog(null, "Sure to delete the Object and all relations with it", "Delete object",JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
if(i==JOptionPane.YES_OPTION){
// 1. 先删除和鼠标右键项有关的所有关系
for (DrawElementWithRelation relatedElementWithRelation : relatedElementsWithRelation) {
cans.removeIcon(relatedElementWithRelation.getRelationDrawElement()); // 删除关系
}
// 2. 线段另一端的图案(指线段的除了鼠标右键项的另一端)的保存文件要重新生成
for (DrawElementWithRelation relatedElementWithRelation : relatedElementsWithRelation) {
if(relatedElementWithRelation.getSpecificType().equals("taskPlanningAgent")){
PlannerAgentCodeGeneratorClient.AgentFileGenerator(mypath, relatedElementWithRelation, cans);
}else if (relatedElementWithRelation.getSpecificType().equals("dispatchAgent")) {
DispatcherAgentCodeGeneratorClient.AgentFileGenerator(mypath, relatedElementWithRelation, cans);
}else if (relatedElementWithRelation.getSpecificType().equals("moveAgent")) {
ActuatorAgentCodeGeneratorClient.AgentFileGenerator(mypath, relatedElementWithRelation, cans);
}else {
System.out.print("No beginele SpecificType meet the condition(in DrawPanel.java function createPopupMenu). ");
System.out.println(relatedElementWithRelation.getSpecificType());
}
}
// 3. 再删除鼠标右键项图案,并删除其文件
cans.removeIcon(drawElementRightClicked);
DeleteFileUtil.delete(mypath + drawElementRightClicked.getFilename());
// 4. 再将当前画板中的图形数据保存下来到.arcgprj
MyCanvas.saveDrawList(mypath +"/.arcgprj", cans.getDrawlist());
// 5. 通知程序左侧树状目录图刷新
ReadTxt.writeFile(this .getClass().getResource( "" ).getPath() + "Modified.ini", "1"); // 写入1通知刷新
}
}
});
pop.add(deleteDrawElementItem);
// ------------创建关系删除菜单--------------
JMenu deleteRelation = new JMenu("delete relation"); // 总菜单项
// 每个单个关系都是一个分菜单项
for (DrawElementWithRelation relatedElementWithRelation : relatedElementsWithRelation) { // 每个DrawElementWithRelation中都存储着一个有关系的图案对象和关系名称还有箭头指向对列表进行循环每次循环都对一个DrawElementWithRelation进行处理
// 将单个关系作为一个菜单分项添加到右键菜单中
String newdrawEleItemText = ""; // 分菜单项中的文字部分
if (relatedElementWithRelation.getArrowDirection() == 0) {
newdrawEleItemText = "delete " + relatedElementWithRelation.getRelation() + " from: " + relatedElementWithRelation.getName();
}else if (relatedElementWithRelation.getArrowDirection() == 1) { // 1表示箭头是由鼠标右键的图案为起始点的
newdrawEleItemText = "delete " + relatedElementWithRelation.getRelation() + " to: " + relatedElementWithRelation.getName();
}else {
System.out.println("Error in drawElePosRelation in DrawJPanel.java");
}
JMenuItem deleteDrawElementRelationItem = new JMenuItem(newdrawEleItemText);
deleteDrawElementRelationItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 选择了删除一个关系以后需要执行的操作:
// 1.从drawlist中删除该线段关系面板重绘
cans.removeIcon(relatedElementWithRelation.getRelationDrawElement());
// 2. 线段两端的图案的保存文件要重新生成
if(drawElementRightClicked.getSpecificType().equals("taskPlanningAgent")){
PlannerAgentCodeGeneratorClient.AgentFileGenerator(mypath, drawElementRightClicked, cans);
}else if (drawElementRightClicked.getSpecificType().equals("dispatchAgent")) {
DispatcherAgentCodeGeneratorClient.AgentFileGenerator(mypath, drawElementRightClicked, cans);
}else if (drawElementRightClicked.getSpecificType().equals("moveAgent")) {
ActuatorAgentCodeGeneratorClient.AgentFileGenerator(mypath, drawElementRightClicked, cans);
}else {
System.out.print("No beginele SpecificType meet the condition(in DrawPanel.java function createPopupMenu). ");
System.out.println(drawElementRightClicked.getSpecificType());
}
if(relatedElementWithRelation.getSpecificType().equals("taskPlanningAgent")){
PlannerAgentCodeGeneratorClient.AgentFileGenerator(mypath, relatedElementWithRelation, cans);
}else if (relatedElementWithRelation.getSpecificType().equals("dispatchAgent")) {
DispatcherAgentCodeGeneratorClient.AgentFileGenerator(mypath, relatedElementWithRelation, cans);
}else if (relatedElementWithRelation.getSpecificType().equals("moveAgent")) {
ActuatorAgentCodeGeneratorClient.AgentFileGenerator(mypath, relatedElementWithRelation, cans);
}else {
System.out.print("No beginele SpecificType meet the condition(in DrawPanel.java function createPopupMenu). ");
System.out.println(relatedElementWithRelation.getSpecificType());
}
// 3. 将当前画板中的图形数据保存下来到.arcgprj
MyCanvas.saveDrawList(mypath +"/.arcgprj", cans.getDrawlist());
}
});
deleteRelation.add(deleteDrawElementRelationItem);
}
pop.add(deleteRelation);
pop.show(this, posX, posY);
}
}

@ -0,0 +1,536 @@
package CodeGenerator;
import java.awt.FileDialog;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.*;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.swing.*;
import javax.swing.undo.UndoManager;
public class EditorJFrame extends JFrame implements ActionListener {
//窗体和输入区域
JPanel pl = new JPanel();
JTextArea myarea = new JTextArea();
private String filename; // 打开的文件名
String textContent = "";// 编辑框中的内容
UndoManager undoManager = new UndoManager();// 撤销管理器
public EditorJFrame(String path) {
this.filename = path;
initComponment(path);// 面板初始化
}
private void initComponment(String path) {
// 菜单栏
JMenuBar mb = new JMenuBar();
// 弹出菜单
final JPopupMenu myPopMenu = new JPopupMenu();
JMenuItem copy_pop = new JMenuItem("Copy");
JMenuItem cut_pop = new JMenuItem("Cut");
JMenuItem paste_pop = new JMenuItem("Paste");
JMenuItem delete_pop = new JMenuItem("Delete");
JMenuItem exit_pop = new JMenuItem("Clean");
myPopMenu.add(cut_pop);
myPopMenu.add(copy_pop);
myPopMenu.add(delete_pop);
myPopMenu.add(paste_pop);
myPopMenu.add(exit_pop);
// 绑定监听器
cut_pop.addActionListener(this);
copy_pop.addActionListener(this);
delete_pop.addActionListener(this);
paste_pop.addActionListener(this);
exit_pop.addActionListener(this);
// 菜单
JMenu file = new JMenu("File");
JMenu edit = new JMenu("Edit");
JMenu about = new JMenu("About");
// 子菜单
JMenuItem new_file = new JMenuItem("New");
JMenuItem open = new JMenuItem("Open");
JMenuItem save = new JMenuItem("Save");
JMenuItem save_as = new JMenuItem("Save As");
JMenuItem exit = new JMenuItem("Quit");
JMenuItem copy = new JMenuItem("Copy");
JMenuItem cut = new JMenuItem("Cut");
JMenuItem paste = new JMenuItem("Paste");
JMenuItem delete = new JMenuItem("Delete");
JMenuItem search = new JMenuItem("Find and Replace");
JMenuItem aboutsoft = new JMenuItem("About Software");
// 绑定监听事件
aboutsoft.addActionListener(this);
new_file.addActionListener(this);
open.addActionListener(this);
save.addActionListener(this);
save_as.addActionListener(this);
exit.addActionListener(this);
copy.addActionListener(this);
cut.addActionListener(this);
paste.addActionListener(this);
delete.addActionListener(this);
search.addActionListener(this);
// 将菜单和相应的子菜单添加到菜单栏
mb.add(file);
mb.add(edit);
mb.add(about);
file.add(open);
file.add(new_file);
file.add(save);
file.add(save_as);
file.add(exit);
edit.add(copy);
edit.add(cut);
edit.add(paste);
edit.add(delete);
edit.add(search);
about.add(aboutsoft);
// 给文本区域添加滚动条
myarea.add(myPopMenu);
JScrollPane scrollpane = new JScrollPane(myarea);
add(scrollpane);
// 主窗口
setTitle("CodeEditor");
setSize(1000, 800);
this.setLocationRelativeTo(null);
// 添加菜单栏
setJMenuBar(mb);
// 窗口监听
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
if(!myarea.getText().equals(textContent))
{
int result = JOptionPane.showConfirmDialog(null, "The file have been modified. Save changes?", "Warning", JOptionPane.YES_NO_OPTION);
switch (result) {
case JOptionPane.NO_OPTION:
//System.exit(0);
setDefaultCloseOperation(HIDE_ON_CLOSE);
break;
case JOptionPane.YES_OPTION:
save();
//System.exit(0);
setDefaultCloseOperation(HIDE_ON_CLOSE);
break;
default:
break;
}
}
else {
//System.exit(0);
setDefaultCloseOperation(HIDE_ON_CLOSE);
}
}
});
//键盘监听
myarea.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent ke)
{
//ctrl+f实现查找功能
if ((ke.getKeyCode() == KeyEvent.VK_F)
&& (ke.isControlDown()))
{
// 查找对话框
JDialog search = new JDialog(EditorJFrame.this, "Find and Replace");
search.setSize(200, 100);
search.setLocation(450, 350);
JLabel label_1 = new JLabel("Find");
JLabel label_2 = new JLabel("Replace");
final JTextField textField_1 = new JTextField(5);
final JTextField textField_2 = new JTextField(5);
JButton buttonFind = new JButton("Find");
JButton buttonChange = new JButton("Replace");
JPanel panel = new JPanel(new GridLayout(2, 3));
panel.add(label_1);
panel.add(textField_1);
panel.add(buttonFind);
panel.add(label_2);
panel.add(textField_2);
panel.add(buttonChange);
search.add(panel);
search.setVisible(true);
// 为查找下一个 按钮绑定监听事件
buttonFind.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String findText = textField_1.getText();// 查找的字符串
String textArea = myarea.getText();// 当前文本框的内容
start = textArea.indexOf(findText, end);
end = start + findText.length();
if (start == -1)// 没有找到
{
JOptionPane.showMessageDialog(null, "“"+findText+"”"+"has been found", "CodeEditor", JOptionPane.WARNING_MESSAGE);
myarea.select(start, end);
} else {
myarea.select(start, end);
}
}
});
// 为替换按钮绑定监听时间
buttonChange.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String changeText = textField_2.getText();// 替换的字符串
myarea.select(start, end);
myarea.replaceSelection(changeText);
myarea.select(start, end);
}
});
}
//esc退出
if (ke.getKeyCode()==KeyEvent.VK_ESCAPE)
{
if(!myarea.getText().equals(textContent))
{
int result = JOptionPane.showConfirmDialog(null, "The file have been modified. Save changes?", "Warning", 1);
switch (result) {
case JOptionPane.NO_OPTION:
//System.exit(0);
setDefaultCloseOperation(HIDE_ON_CLOSE);
break;
case JOptionPane.YES_OPTION:
save();
//System.exit(0);
setDefaultCloseOperation(HIDE_ON_CLOSE);
break;
case JOptionPane.CANCEL_OPTION:
break;
default:
break;
}
}
}
}
});
// 鼠标监听
myarea.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
int mods = e.getModifiers();
// 鼠标右键
if ((mods & InputEvent.BUTTON3_MASK) != 0) {
// 弹出菜单
myPopMenu.show(e.getComponent(), e.getX(), e.getY());
}
}
});
this.setVisible(true);
this.OpenFile(this.filename);
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
}
// 相关变量
int start = 0;// 查找开始位置
int end = 0;// 查找结束位置
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
try {
if (e.getActionCommand() == "New") {
myarea.setText("");
} else if (e.getActionCommand() == "Open") {
FileDialog fileDialog = new FileDialog(this, "Open File", FileDialog.LOAD);
fileDialog.setVisible(true);
if (fileDialog.getFile() != null) {
filename = fileDialog.getDirectory() + fileDialog.getFile();// 获得文件名
this.OpenFile(filename);
}
} else if (e.getActionCommand() == "Save") {
save();
} else if (e.getActionCommand() == "Save As") {
otherSave();
} else if (e.getActionCommand() == "Quit") {
if(!myarea.getText().equals(textContent))
{
int result = JOptionPane.showConfirmDialog(null, "The file have been modified. Save changes?", "Warning", 1);
switch (result) {
case JOptionPane.NO_OPTION:
//System.exit(0);
setDefaultCloseOperation(HIDE_ON_CLOSE);
break;
case JOptionPane.YES_OPTION:
save();
//System.exit(0);
setDefaultCloseOperation(HIDE_ON_CLOSE);
break;
case JOptionPane.CANCEL_OPTION:
break;
default:
break;
}
}
else {
System.exit(0);
}
} else if (e.getActionCommand() == "Find and Replace") {
// 查找对话框
JDialog search = new JDialog(this, "Find and Replace");
search.setSize(200, 100);
search.setLocation(450, 350);
JLabel label_1 = new JLabel("Find");
JLabel label_2 = new JLabel("Replace");
final JTextField textField_1 = new JTextField(5);
final JTextField textField_2 = new JTextField(5);
JButton buttonFind = new JButton("Find");
JButton buttonChange = new JButton("Replace");
JPanel panel = new JPanel(new GridLayout(2, 3));
panel.add(label_1);
panel.add(textField_1);
panel.add(buttonFind);
panel.add(label_2);
panel.add(textField_2);
panel.add(buttonChange);
search.add(panel);
search.setVisible(true);
// 为查找下一个 按钮绑定监听事件
buttonFind.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String findText = textField_1.getText();// 查找的字符串
String textArea = myarea.getText();// 当前文本框的内容
start = textArea.indexOf(findText, end);
end = start + findText.length();
// 没有找到
if (start == -1)
{
JOptionPane.showMessageDialog(null, "“"+findText+"”"+"has been found", "CodeEditor", JOptionPane.WARNING_MESSAGE);
myarea.select(start, end);
} else {
myarea.select(start, end);
}
}
});
// 为替换按钮绑定监听事件
buttonChange.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String changeText = textField_2.getText();// 替换的字符串
myarea.select(start, end);
myarea.replaceSelection(changeText);
myarea.select(start, end);
}
});
} else if (e.getActionCommand() == "Copy") {
copy();
} else if (e.getActionCommand() == "Paste") {
paste();
} else if (e.getActionCommand() == "Cut") {
cut();
} else if (e.getActionCommand() == "Delete") {
delete();
} else if (e.getActionCommand() == "About Software") {
JOptionPane.showMessageDialog(null,"单金伟设计编写","软件信息",JOptionPane. INFORMATION_MESSAGE);
}else if (e.getActionCommand() == "Clean")
{
int result = JOptionPane.showConfirmDialog(null, "Clean all?", "Warning", 1);
if (result == JOptionPane.OK_OPTION) {
// myarea.replaceRange(null,0,textContent.length());
myarea.setText(null);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void OpenFile(String path) {
// 读取文件
FileReader file_reader;
try {
file_reader = new FileReader(path);
BufferedReader br = new BufferedReader(file_reader);
String temp = "";
while (br.ready())// 判断缓冲区是否为空非空时返回true
{
int c = br.read();
temp = temp+ (char)c;
}
myarea.setText(temp);
br.close();
file_reader.close();
textContent = myarea.getText();
setTitle("CodeEditor-" + path);
} catch (IOException e) {
JOptionPane.showMessageDialog(this, "No File");
}// 此处必须要捕获异常
}
//保存
private void save() {
if (filename != null)
{
try {
File file = new File(filename);
FileWriter file_writer = new FileWriter(file);
//将文件输出流包装进缓冲区
BufferedWriter bw = new BufferedWriter(file_writer);
PrintWriter pw = new PrintWriter(bw);
pw.print(myarea.getText());
textContent = myarea.getText();
pw.close();
bw.close();
file_writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}else {
otherSave();
}
}
//另存为
private void otherSave()
{
FileDialog fileDialog = new FileDialog(this, "Save As", FileDialog.SAVE);
fileDialog.setFile("*.txt");
fileDialog.setVisible(true);
if (fileDialog.getFile() != null) {
// 写入文件
FileWriter fw;
try {
fw = new FileWriter(fileDialog.getDirectory() + fileDialog.getFile());
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter pw = new PrintWriter(bw);
pw.print(myarea.getText());
textContent = myarea.getText();
pw.close();
bw.close();
fw.close();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//剪切
private void cut() {
copy();
delete();
}
//复制
private void copy() {
if (myarea.getSelectedText() == null) {
JOptionPane.showMessageDialog(null, "Nothing!", "CodeEditor", JOptionPane.WARNING_MESSAGE);
}
Clipboard clipBoard = Toolkit.getDefaultToolkit().getSystemClipboard();
StringSelection stringSelection = new StringSelection(myarea.getSelectedText());
clipBoard.setContents(stringSelection, null);
}
//粘贴
private void paste() throws UnsupportedFlavorException, IOException {
String content_copy = "";
// 构造系统剪切板
Clipboard clipBoard = Toolkit.getDefaultToolkit().getSystemClipboard();
// 获取剪切板内容
Transferable content = clipBoard.getContents(null);
if (content != null) {
// 检查是否是文本类型
if (content.isDataFlavorSupported(DataFlavor.stringFlavor)) {
content_copy = (String) content.getTransferData(DataFlavor.stringFlavor);
// 判断文本框中有无文字选中
if (myarea.getSelectedText() != null) {
myarea.replaceSelection(content_copy);
} else {
myarea.insert(content_copy, myarea.getSelectionStart());
}
}
}
}
//删除
private void delete() {
if (myarea.getSelectedText() == null) {
JOptionPane.showMessageDialog(null, "Nothing!", "CodeEditor", JOptionPane.WARNING_MESSAGE);
}
myarea.replaceSelection("");
}
}

@ -0,0 +1,127 @@
package CodeGenerator;
import java.util.List;
/**
*
* @author lvzb.software@qq.com
*
*/
public class Entity {
// 实体所在的包名
private String javaPackage;
// 实体类名
private String className;
// 父类名
private String superclass;
// 属性集合
List<Property> properties;
//属性(方法)集合
List<Entity> tbentities;
List<Entity> tbfentities;
List<DrawElementWithRelation> postiveRelatedElementsWithRelation;
List<DrawElementWithRelation> negativeRelatedElementsWithRelation;
List<DrawElement> allRelatedElements;
private String specificType;// 表示对象具体属于哪种类型用于显示Id
// 是否有构造函数
private boolean constructors;
public String getJavaPackage() {
return javaPackage;
}
public void setJavaPackage(String javaPackage) {
this.javaPackage = javaPackage;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getSuperclass() {
return superclass;
}
public void setSuperclass(String superclass) {
this.superclass = superclass;
}
public List<Property> getProperties() {
return properties;
}
public void setProperties(List<Property> properties) {
this.properties = properties;
}
public List<Entity> getEntities(){
return tbentities;
}
public void setEntities(List<Entity> tbentities) {
this.tbentities = tbentities;
}
public List<Entity> getTbfEntities(){
return tbfentities;
}
public void setTbfEntities(List<Entity> tbfentities) {
this.tbfentities = tbfentities;
}
public boolean isConstructors() {
return constructors;
}
public void setConstructors(boolean constructors) {
this.constructors = constructors;
}
public List<DrawElementWithRelation> getPostiveRelatedElementsWithRelation() { //注意要在ftl文件中使用必须要写get方法
return postiveRelatedElementsWithRelation;
}
public void setPostiveRelatedElementsWithRelation(
List<DrawElementWithRelation> postiveRelatedElementsWithRelation) {
// TODO 自动生成的方法存根
this.postiveRelatedElementsWithRelation = postiveRelatedElementsWithRelation;
}
public List<DrawElementWithRelation> getNegativeRelatedElementsWithRelation() {
return negativeRelatedElementsWithRelation;
}
public void setNegativeRelatedElementsWithRelation(
List<DrawElementWithRelation> negativeRelatedElementsWithRelation) {
// TODO 自动生成的方法存根
this.negativeRelatedElementsWithRelation = negativeRelatedElementsWithRelation;
}
public List<DrawElement> getAllRelatedElements() {
return allRelatedElements;
}
public void setAllRelatedElements(
List<DrawElement> allRelatedElements) {
// TODO 自动生成的方法存根
this.allRelatedElements = allRelatedElements;
}
public void setSpecificType(String specificType) {
// TODO 自动生成的方法存根
this.specificType = specificType;
}
public String getSpecificType() {
return specificType;
}
}

@ -0,0 +1,78 @@
package CodeGenerator;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
public class FileUtils {
public static void Write(String path,String write,int linecount) {
int intcount = linecount;
File filesave =new File(path);
try {
FileReader fin = new FileReader(filesave);
BufferedReader bin = new BufferedReader(fin);
String line = "";
ArrayList<String>templist = new ArrayList<String>();
while((line = bin.readLine())!=null) {
templist.add(line);
}
FileOutputStream fos = new FileOutputStream(filesave);
PrintWriter pw = new PrintWriter(fos);
for(int i=0;i<templist.size();i++) {
if(i<intcount-1) {
pw.println(templist.get(i));
}else {
pw.println(write);
pw.println(templist.get(i));
intcount = Integer.MAX_VALUE;
}
}
if(intcount != Integer.MAX_VALUE) {
pw.println(write);
}
pw.close();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static ArrayList<String> reader(String path) {
File filesave =new File(path);
ArrayList<String>templist = new ArrayList<String>();
try {
FileReader fin = new FileReader(filesave);
BufferedReader bin = new BufferedReader(fin);
String line = "";
while((line = bin.readLine())!=null) {
templist.add(line);
}
bin.close();
fin.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return templist;
}
public static void createFile(String path ,String name) {
File file = new File(path+"//"+name);
if(!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

@ -0,0 +1,220 @@
package CodeGenerator;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.beans.PropertyVetoException;
import java.io.File;
import java.io.FileFilter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class GramJPanel extends JPanel implements FocusListener, MouseListener{
private int x=-220;
private int y=10;
private int maxlen = 0;
public GramJPanel(String filepath) {
super();
this.setLayout(null);
//this.setPreferredSize(new Dimension(200,100));
List<Class> clazzs = new ArrayList<Class>();
File file = new File(filepath);
String filepath2 = file.getAbsolutePath().replaceAll("src", "bin");
String packageName = file.getName();
if(packageName.equals("src")) {
packageName = "";
}
GramJPanel.findClassInPackageByFile(filepath2,true,clazzs);
for(Class c:clazzs) {
this.addClass(c);
}
}
public void addClass(Class clazz) {
Clazzs c = getClazzs(clazz);
if(c == null) {
return;
}
JInternalFrame internaljframe = new JInternalFrame(c.getName()+"<Java Class>");
internaljframe.addFocusListener(this);
internaljframe.setLayout(new GridLayout(1,1));
JTextArea text = new JTextArea();
text.setBackground(new Color(254,254,200));
text.setEditable(false);
text.setName(c.getFile().getAbsolutePath());
text.setWrapStyleWord(true);
text.addMouseListener(this);
for(String s:c.getFields()) {
text.append(s+"\n");
}
text.append("----------------------------------------------------------------------"+"\n");
for(String s:c.getMethods()) {
text.append(s+"\n");
}
internaljframe.add(text);
int len = (c.getFields().size() + c.getMethods().size()+1)*20+18;
System.out.println(maxlen);
System.out.println(len);
internaljframe.setSize(220, len);
if((x+380) >= 800) {
x=-220;
y=y+maxlen+25;
maxlen = 0;
}
maxlen = maxlen>len?maxlen:len;
internaljframe.setLocation((x=x+230), y);
internaljframe.setBackground(new Color(254,254,200));
internaljframe.setBorder(null);
internaljframe.putClientProperty("JInternalFrame.isPalette", Boolean.TRUE);
//internaljframe.setFrameIcon(null);
//internaljframe.setBackground(Color.white);
//internaljframe.setOpaque(false);
//internaljframe.toFront();
this.add(internaljframe);
internaljframe.setVisible(true);
}
public Clazzs getClazzs(Class clazz) {
Clazzs c = new Clazzs();
if(clazz != null) {
c.setName(clazz.getSimpleName());
Field[] fields = clazz.getDeclaredFields();
for(Field f : fields) {
String fie = f.getModifiers()%2==1?"+":"-";
fie = fie+" "+f.getName()+" : "+f.getType().getSimpleName();
/*if(fie.length()>24) {
StringBuilder sb = new StringBuilder(fie);////构造一个StringBuilder对象
sb.insert(24, "\n ");////在指定的位置1插入指定的字符串
fie = sb.toString();
}*/
c.getFields().add(fie);
}
Method[] methods = clazz.getDeclaredMethods();
for(Method m : methods) {
String meth = m.getModifiers()%2==1?"+":"-";
meth = meth+" "+m.getName()+"() : "+m.getReturnType().getSimpleName();
/*if(meth.length()>24) {
StringBuilder sb = new StringBuilder(meth);//构造一个StringBuilder对象
sb.insert(24, "\n ");//在指定的位置1插入指定的字符串
meth = sb.toString();
}*/
c.getMethods().add(meth);
}
String str1 = clazz.getResource("").toString();
String str2 = clazz.getSimpleName();
String str3 = str1.replaceAll("bin", "src");
String str4 = "/" + str3.substring(6)+str2+".java";
File file = new File(str4);
if(!file.exists()) {
return null;
}else {
c.setFile(file);
}
}
return c;
}
public static void findClassInPackageByFile(String filePath, final boolean recursive, List<Class> clazzs) {
File dir = new File(filePath);
if (!dir.exists() || !dir.isDirectory()) {
return;
}
// 在给定的目录下找到所有的文件,并且进行条件过滤
File[] dirFiles = dir.listFiles(new FileFilter() {
public boolean accept(File file) {
boolean acceptDir = recursive && file.isDirectory();//接受dir目录
boolean acceptClass = file.getName().endsWith("class");//接受class文件
return acceptDir || acceptClass;
}
});
for (File file : dirFiles) {
if (file.isDirectory()) {
findClassInPackageByFile(file.getAbsolutePath(), recursive, clazzs);
} else {
String className = file.getName().substring(0, file.getName().length() - 6);
try {
String filepath = file.getAbsolutePath();
int index = filepath.indexOf("bin")+4;
int end = filepath.length()-className.length()-7;
String packageName = "";
if(index <= end) {
packageName = filepath.substring(index ,end );
packageName = packageName.replace('\\', '.');
}
String str = packageName.equals("")?className:(packageName + "." + className);
//clazzs.add(Thread.currentThread().getContextClassLoader().loadClass(str));
clazzs.add(Class.forName(str));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
@Override
public void focusGained(FocusEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void focusLost(FocusEvent arg0) {
// TODO Auto-generated method stub
}
/*
@Override
public void mouseClicked(MouseEvent e) {
if(e.getSource() instanceof JTextArea) {
JTextArea text = (JTextArea)e.getSource();
System.out.println(text.getName());
}
}
*/
public void mouseClicked(MouseEvent e) {
CodeEditor codeeditor = new CodeEditor();
}
@Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}

@ -0,0 +1,236 @@
package CodeGenerator;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.beans.PropertyVetoException;
import java.io.File;
import java.io.FileFilter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class GramJPanell extends JPanel implements FocusListener, MouseListener{
private int x=-220;
private int y=10;
private int maxlen = 0;
public GramJPanell(String filepath) {
super();
this.setLayout(null);
//this.setPreferredSize(new Dimension(0,0));
List<Class> clazzs = new ArrayList<Class>();
File file = new File(filepath);
String filepath2 = file.getAbsolutePath().replaceAll("src", "bin");
System.out.println(filepath2);
String packageName = file.getName();
if(packageName.equals("src")) {
packageName = "";
}
GramJPanell.findClassInPackageByFile(filepath2,true,clazzs);
for(Class c:clazzs) {
this.addClass(c);
}
}
public void addClass(Class clazz) {
Clazzs c = getClazzs(clazz);
if(c == null) {
return;
}
JInternalFrame internaljframe = new JInternalFrame();
internaljframe.addFocusListener(this);
internaljframe.setLayout(new GridLayout(1,1));
JTextArea text = new JTextArea();
text.setBackground(new Color(254,254,200));
text.setEditable(false);
text.setName(c.getFile().getAbsolutePath());
text.addMouseListener(this);
String title = c.getName();
for(int i = 0;i<(28-c.getName().length())/2;i++) {
title = " " + title;
}
text.append(title+"\n");
text.append(" <Java Class>"+"\n");
//text.append(c.getName()+"\n"+"<Java Class>"+"\n");
text.append("----------------------------------------------------------------------"+"\n");
for(String s:c.getFields()) {
text.append(s+"\n");
}
text.append("----------------------------------------------------------------------"+"\n");
for(String s:c.getMethods()) {
text.append(s+"\n");
}
internaljframe.add(text);
int len = (c.getFields().size() + c.getMethods().size()+4)*17;
internaljframe.setSize(300, len);
if((x+380) >= 800) {
x=-220;
y=y+maxlen+25;
maxlen = 0;
}
maxlen = maxlen>len?maxlen:len;
internaljframe.setLocation((x=x+230), y);
internaljframe.setBackground(new Color(254,254,200));
internaljframe.setBorder(null);
internaljframe.setFrameIcon(null);
//internaljframe.setBackground(Color.white);
//internaljframe.setOpaque(false);
//internaljframe.toFront();
this.add(internaljframe);
internaljframe.setVisible(true);
}
public Clazzs getClazzs(Class clazz) {
Clazzs c = new Clazzs();
if(clazz != null) {
c.setName(clazz.getSimpleName());
Field[] fields = clazz.getDeclaredFields();
for(Field f : fields) {
String fie = f.getModifiers()%2==1?"+":"-";
fie = fie+" "+f.getName()+" : "+f.getType().getSimpleName();
/*if(fie.length()>24) {
StringBuilder sb = new StringBuilder(fie);//构造一个StringBuilder对象
sb.insert(24, "\n ");//在指定的位置1插入指定的字符串
fie = sb.toString();
}*/
c.getFields().add(fie);
}
Method[] methods = clazz.getDeclaredMethods();
for(Method m : methods) {
String meth = m.getModifiers()%2==1?"+":"-";
meth = meth+" "+m.getName()+"() : "+m.getReturnType().getSimpleName();
/*if(meth.length()>24) {
StringBuilder sb = new StringBuilder(meth);//构造一个StringBuilder对象
sb.insert(24, "\n ");//在指定的位置1插入指定的字符串
meth = sb.toString();
}*/
c.getMethods().add(meth);
}
String str1 = clazz.getResource("").toString();
String str2 = clazz.getSimpleName();
String str3 = str1.replaceAll("bin", "src");
String str4 = "/" + str3.substring(6)+str2+".java";
File file = new File(str4);
if(!file.exists()) {
return null;
}else {
c.setFile(file);
}
}
return c;
}
public static void findClassInPackageByFile(String filePath, final boolean recursive, List<Class> clazzs) {
/*
* filePathjavaClass
*/
filePath = filePath.replaceAll("\\\\", "\\\\\\\\"); // java中要将单反斜杠换成双反斜杠
File dir = new File(filePath);
if (!dir.exists()) {
System.out.println(dir.getAbsolutePath());
return;
}
// 在给定的目录下找到所有的文件,并且进行条件过滤
File[] dirFiles = dir.listFiles(new FileFilter() {
public boolean accept(File file) {
boolean acceptDir = recursive && file.isDirectory();//接受dir目录
boolean acceptClass = file.getName().endsWith("class");//接受class文件
return acceptDir || acceptClass;
}
});
for (File file : dirFiles) {
System.out.println(file.getPath());
if (file.isDirectory()) {
findClassInPackageByFile(file.getAbsolutePath(), recursive, clazzs);
} else {
String className = file.getName().substring(0, file.getName().length() - 6);
try {
String filepath = file.getAbsolutePath();
int index = filepath.indexOf("bin")+4;
int end = filepath.length()-className.length()-7;
String packageName = "";
if(index <= end) {
packageName = filepath.substring(index ,end );
packageName = packageName.replace('\\', '.');
}
String str = packageName.equals("")?className:(packageName + "." + className);
//clazzs.add(Thread.currentThread().getContextClassLoader().loadClass(str));
System.out.println(str);
System.out.println("okokokoko");
clazzs.add(Class.forName(str));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
@Override
public void focusGained(FocusEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void focusLost(FocusEvent arg0) {
// TODO Auto-generated method stub
}
@Override
/*public void mouseClicked(MouseEvent e) {
if(e.getSource() instanceof JTextArea) {
JTextArea text = (JTextArea)e.getSource();
System.out.println(text.getName());
}
}
*/
public void mouseClicked(MouseEvent e) {
//CodeEditor codeeditor = new CodeEditor();
JTextArea text = (JTextArea)e.getSource();
EditorJFrame ejd = new EditorJFrame(text.getName());
}
@Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}

@ -0,0 +1,77 @@
package CodeGenerator;
import javax.swing.Icon;
import javax.swing.tree.DefaultMutableTreeNode;
//定义节点类
class IconNode extends DefaultMutableTreeNode
{
protected Icon icon;
protected String txt;
protected String filePath; // 文件/文件夹的全路径
//只包含文本的节点构造
public IconNode(String txt)
{
super();
this.txt=txt;
}
//包含文本和图片的节点构造
public IconNode(Icon icon,String txt)
{
super();
this.icon = icon;
this.txt = txt;
}
// 默认不带参数的构造方法
public IconNode()
{
super();
}
/*
*
*/
public IconNode(Object userObject, boolean allowsChildren)
{
super(userObject, allowsChildren);
this.txt = userObject.toString();
}
public IconNode(IconNode node) {
super(node);
this.txt = node.toString();
}
public void setIcon(Icon icon)
{
this.icon = icon;
}
public Icon getIcon()
{
return icon;
}
public void setText(String txt)
{
this.txt=txt;
}
public String getText()
{
return txt;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public String getFilePath() {
return this.filePath;
}
}

@ -0,0 +1,23 @@
package CodeGenerator;
import java.awt.Component;
import java.awt.Font;
import javax.swing.Icon;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeCellRenderer;
public class IconNodeRenderer extends DefaultTreeCellRenderer//继承该类
{
//重写该方法
public Component getTreeCellRendererComponent(JTree tree, Object value,boolean sel, boolean expanded, boolean leaf, int row,boolean hasFocus)
{
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf,row, hasFocus); //调用父类的该方法
Icon icon = ((IconNode) value).getIcon();//从节点读取图片
String txt=((IconNode) value).getText(); //从节点读取文本
setIcon(icon);//设置图片
setText(txt);//设置文本
setFont(new Font("Default",Font.PLAIN,13));//设置树的整体字体样式Serif
return this;
}
}

@ -0,0 +1,50 @@
package CodeGenerator;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.io.File;
import java.io.IOException;
import javax.swing.JFrame;
/**
*
*/
public class ImageFrame extends JFrame {
//初始化屏幕的尺寸
private Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
public ImageFrame() {
super("test");
this.setSize((int)screenSize.getWidth()/3,(int)(screenSize.getHeight()/1.5));
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setLayout(new GridLayout(1,1));
DrawJPanel panel = new DrawJPanel("src//code");
this.add(panel);
this.setVisible(true);
}
public static void main(String args[]) {
new ImageFrame();
/*File file = new File("src//code//123.java");
System.out.println(file.getAbsolutePath());
if(!file.exists()) {
System.out.println(1321);
try {
file.createNewFile();
System.out.println("csafcknj");
} catch (IOException e) {
e.printStackTrace();
}
}
FileUtils.Write(file.getAbsolutePath(), "1321");*/
}
}

@ -0,0 +1,126 @@
package CodeGenerator;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import CodeGenerator.DrawElement;
import CodeGenerator.MyCanvas;
//import CodeGenerator.AgentCodeGeneratorClient2;
public class JavaJFrame extends JFrame implements ActionListener {
private JTextField textField;
private JTextField textField_1;
private JTextField textField_2;
private JButton createAgentButton;
private DrawElement drawelement;
private MyCanvas cans;
String mypath = "";
private JComboBox <String> comboBoxAgentType;
public JavaJFrame(String path,DrawElement drawelement,MyCanvas cans) {
super("Create Agent");
this.mypath = path;
this.drawelement = drawelement;
this.cans = cans;
this.setLayout(null);
this.setBounds(0, 0, 450, 180);
JLabel lblAgentName = new JLabel("Agent Name:");
lblAgentName.setBounds(53, 24, 100, 16);
this.add(lblAgentName);
JLabel lblAgentType = new JLabel("Agent Type:");
lblAgentType.setBounds(53, 63, 100, 16);
this.add(lblAgentType);
textField = new JTextField();
textField.setBounds(196, 19, 217, 26);
this.add(textField);
textField.setColumns(10);
comboBoxAgentType = new JComboBox();
comboBoxAgentType.setBounds(196, 59, 217, 27);
this.add(comboBoxAgentType);
comboBoxAgentType.addItem("Planner Agent");
comboBoxAgentType.addItem("Dispatcher Agent");
comboBoxAgentType.addItem("Sensor Agent");
comboBoxAgentType.addItem("Actuator Agent");
createAgentButton = new JButton("Create Agent");
createAgentButton.setBounds(276, 98, 137, 29);
this.add(createAgentButton);
createAgentButton.addActionListener(this);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
MyCanvas tempCans = cans; // 必须创建这两个局部变量才能在下面的windowClosing事件中访问到
DrawElement tempDrawElement = drawelement;
this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); // 捕捉关闭窗口事件
this.addWindowListener(new WindowAdapter() { // 捕捉到窗口关闭事件
public void windowClosing(WindowEvent e) {
/*
*code for example:
int i=JOptionPane.showConfirmDialog(null, "确定要退出系统吗?", "退出系统", JOptionPane.YES_NO_OPTION);
if(i==JOptionPane.YES_OPTION){
System.exit(0);
}
*/
// 如果未按下选择关系的按钮退出,而是选择按右上角的关闭对话框按钮,会触发该事件
// 触发该事件后我们要将之前已经添加到drawlist中的templist删除
tempCans.removeIcon(tempDrawElement);
dispose();
}
});
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == this.createAgentButton) {
String name = this.textField.getText();
String type = (String)this.comboBoxAgentType.getSelectedItem();
if(name!=null&&!name.equals("")) {
drawelement.setName(name);
}
//FileUtils.createFile(mypath, drawelement.getName()+".java");
if (type == "Planner Agent")
{
this.drawelement.setSpecificType("taskPlanningAgent"); // 在ChooseRelationJFrame中会根据不同类型的Agent生成不同的代码
PlannerAgentCodeGeneratorClient.AgentFileGenerator(mypath, drawelement, cans);
}
else if (type == "Dispatcher Agent")
{
this.drawelement.setSpecificType("dispatchAgent");
DispatcherAgentCodeGeneratorClient.AgentFileGenerator(mypath, drawelement, cans);
}
else if (type == "Sensor Agent")
{
this.drawelement.setSpecificType("SensorAgent");
SensorAgentCodeGeneratorClient.AgentFileGenerator(mypath, drawelement, cans);
}
else
{
this.drawelement.setSpecificType("moveAgent");
ActuatorAgentCodeGeneratorClient.AgentFileGenerator(mypath, drawelement, cans);
}
drawelement.setFilename("//Agent//"+drawelement.getName()+".java");
MyCanvas.saveDrawList(this.mypath +"/.arcgprj", this.cans.getDrawlist());
cans.repaint();
ReadTxt.writeFile(this .getClass().getResource( "" ).getPath() + "Modified.ini", "1"); // 写入1通知刷新
this.dispose();
}
}
}

@ -0,0 +1,30 @@
package CodeGenerator;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.web.WebView;
public class JavaOpenSafari {
public static void main(String args[]) {
if (java.awt.Desktop.isDesktopSupported()) {
try {
// 创建一个URI实例
java.net.URI uri = java.net.URI.create("http://www.cnblogs.com/lsgwr/");
// 获取当前系统桌面扩展
java.awt.Desktop dp = java.awt.Desktop.getDesktop();
// 判断系统桌面是否支持要执行的功能
if (dp.isSupported(java.awt.Desktop.Action.BROWSE)) {
// 获取系统默认浏览器打开链接
dp.browse(uri);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

@ -0,0 +1,369 @@
package CodeGenerator;
import java.awt.Canvas;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ImageIcon;
import sun.security.util.Length;
import com.sun.prism.paint.LinearGradient;
// Java绘图参考https://blog.csdn.net/xietansheng/article/details/55669157
public class MyCanvas extends Canvas{
private int size = 47; // 图案的默认大小
private ArrayList<DrawElement> drawlist = new ArrayList<DrawElement>(); // 画布上所有的绘图,列表中的每个元素都是单个绘图(一个图案或者一条直线)
public void addIcon(DrawElement drawelement) { // 添加一个图案/线条并重绘画板
this.drawlist.add(drawelement); // 保存到列表中,成为一条绘图记录(一个记录就是一个图案或者一条直线)
this.repaint();
// 在改变drawlist之后都应该写入画板文件保存但是该类中没有项目路径所以我们先使用addIcon在画板上添加一个默认的图案在弹出对话框确定图案名称或者图案之间关系之后自动保存画板数据
}
public Boolean removeIcon(DrawElement drawelement) { // 将列表中和drawelement名字相同的就删除掉
for(int i=0;i<this.drawlist.size();i++){
if(this.drawlist.get(i).getType() == drawelement.getType()) { // 类型相同的再进行下一步判断
if (drawelement.getType() == 1){ // 两个都是图案
if (this.drawlist.get(i).getName() == drawelement.getName()){ //图案的名字相同即可
this.drawlist.remove(this.drawlist.get(i));
this.repaint();
return true;
}
}else if (drawelement.getType() == 2) { // 两个都是线段
if (this.drawlist.get(i).getDrawlist().get(0).getP1()==drawelement.getDrawlist().get(0).getP1() &&
this.drawlist.get(i).getDrawlist().get(1).getP1()==drawelement.getDrawlist().get(1).getP1() ){ // 线段的起始点和结束点相同即可
this.drawlist.remove(this.drawlist.get(i));
this.repaint();
return true;
}
}else {
System.out.println("Unknown type of drawelement in MyCanvas.java");
}
}
}
return false;
}
public void addName(DrawElement drawelement) { // 在图案下面写上name
Graphics g = this.getGraphics();
int x = (int)drawelement.getP1().getX();
int y = (int)drawelement.getP1().getY();
g.setFont(new Font("Tahoma", Font.BOLD, 12));
g.drawString(drawelement.getName(), x, y+size+20);
}
public void drawAL(int sx, int sy, int ex, int ey, Graphics2D g2) {
double H = 10; // 箭头高度
double L = 4; // 底边的一半
int x3 = 0;
int y3 = 0;
int x4 = 0;
int y4 = 0;
double awrad = Math.atan(L / H); // 箭头角度
double arraow_len = Math.sqrt(L * L + H * H); // 箭头的长度
double[] arrXY_1 = rotateVec(ex - sx, ey - sy, awrad, true, arraow_len);
double[] arrXY_2 = rotateVec(ex - sx, ey - sy, -awrad, true, arraow_len);
double x_3 = ex - arrXY_1[0]; // (x3,y3)是第一端点
double y_3 = ey - arrXY_1[1];
double x_4 = ex - arrXY_2[0]; // (x4,y4)是第二端点
double y_4 = ey - arrXY_2[1];
Double X3 = new Double(x_3);
x3 = X3.intValue();
Double Y3 = new Double(y_3);
y3 = Y3.intValue();
Double X4 = new Double(x_4);
x4 = X4.intValue();
Double Y4 = new Double(y_4);
y4 = Y4.intValue();
// 画线
g2.drawLine(sx, sy, ex, ey);
//
GeneralPath triangle = new GeneralPath();
triangle.moveTo(ex, ey);
triangle.lineTo(x3, y3);
triangle.lineTo(x4, y4);
triangle.closePath();
//实心箭头
g2.fill(triangle);
//非实心箭头
//g2.draw(triangle);
}
// 计算
public double[] rotateVec(int px, int py, double ang,boolean isChLen, double newLen) {
double mathstr[] = new double[2];
// 矢量旋转函数参数含义分别是x分量、y分量、旋转角、是否改变长度、新长度
double vx = px * Math.cos(ang) - py * Math.sin(ang);
double vy = px * Math.sin(ang) + py * Math.cos(ang);
if (isChLen) {
double d = Math.sqrt(vx * vx + vy * vy);
vx = vx / d * newLen;
vy = vy / d * newLen;
mathstr[0] = vx;
mathstr[1] = vy;
}
return mathstr;
}
// 画带注释的箭头
public void drawALWithNote(int sx, int sy, int ex, int ey, Graphics2D g2, String noteText, Boolean noteRelativePos){
drawAL(sx, sy, ex, ey, g2); // 先画直线
double noteInclinationAngle = 0; // 计算字体倾斜角,弧度制
if (sx != ex){ //斜率可计算
double lineGradient = (ey-sy)/(new Double(ex-sx));
noteInclinationAngle = Math.atan(lineGradient);
}else{ // 斜率不可计算
noteInclinationAngle = -1.57;
}
if(noteRelativePos){ // noteRelativePos为true时表示文字在线段的上方
Font font = new Font(null, Font.PLAIN, 12);
AffineTransform affineTransform = new AffineTransform();
affineTransform.rotate(noteInclinationAngle, 0, 0); // 旋转角度
Font rotatedFont = font.deriveFont(affineTransform);
g2.setFont(rotatedFont);
// 为了使字符串不从线段正中间开始画,将字符串修正使得字符串处于线段正中央,不同位置的修正程度不一样
g2.drawString(noteText,(int) ((sx+ex)/2 - noteText.length()*3.0 * Math.cos(noteInclinationAngle) + 3.0 * Math.sin(noteInclinationAngle)),(int) ((sy+ey)/2 - noteText.length()*3.0 * Math.sin(noteInclinationAngle)));
}
else { // 文字在线段下方
Font font = new Font(null, Font.PLAIN, 12);
AffineTransform affineTransform = new AffineTransform();
affineTransform.rotate(noteInclinationAngle, 0, 0); // 旋转角度
Font rotatedFont = font.deriveFont(affineTransform);
g2.setFont(rotatedFont);
g2.drawString(noteText,(int) ((sx+ex)/2 - noteText.length()*3.0 * Math.cos(noteInclinationAngle) - 12* Math.sin(noteInclinationAngle)),(int) ((sy+ey)/2 - noteText.length()*3.0 * Math.sin(noteInclinationAngle) + Math.cos(noteInclinationAngle)*12));
}
}
public void paint(Graphics g) {
/*
// 画字符串示例代码
Graphics2D g2 = (Graphics2D) g;
Font font = new Font(null, Font.PLAIN, 12);
AffineTransform affineTransform = new AffineTransform();
affineTransform.rotate(Math.toRadians(0), 0, 0); // 旋转角度
Font rotatedFont = font.deriveFont(affineTransform);
g2.setFont(rotatedFont);
g2.drawString("A String getgetGetHF",50,50); // 绘制的字符串
//g2.dispose();
*/
ArrayList<DrawElement> hasPaintedElementArrayList = new ArrayList<DrawElement>();
for(DrawElement drawelement:drawlist) {//对drawlist即所有图像和线段进行重绘
if(drawelement.getType() == 1) {
int x = (int)drawelement.getP1().getX();
int y = (int)drawelement.getP1().getY();
Image image = new ImageIcon(drawelement.getPath()).getImage();
g.drawImage(image, x, y,size,size, this); // 画图案
g.setFont(new Font("Tahoma", Font.BOLD, 12));
g.drawString(drawelement.getName(), x, y+size+20);// 画图案的名字
}
if(drawelement.getType() == 2) {
if (isReverseInDrawlist(drawelement, hasPaintedElementArrayList)){ // 如果该线段已经添加过并且与即将要添加的drawelement线段方向相反
Point begin = drawelement.getDrawlist().get(0).getP1();
Point end = drawelement.getDrawlist().get(1).getP1();
String relation = drawelement.getName();
// Drawlist中获取到的是线条起始点和结束点需要根据两个图案的相对位置进一步确定
int xx1 = (int)begin.getX()+size/2; // 此时xx1的值是第一个图案的中心点
int yy1 = (int)begin.getY()+size/2;
int xx2 = (int)end.getX()+size/2;
int yy2 = (int)end.getY()+size/2;
if(xx1 < xx2) {
if(Math.abs(xx1-xx2)>Math.abs(yy1-yy2)) {
xx1 = xx1+size/2;
xx2 = xx2-size/2;
yy1 += 10;
yy2 += 10;
}else {
if(yy1>yy2) {
yy2 += size/2;
yy1 -= size/2;
xx1 += 10;
xx2 += 10;
}else {
yy1 += size/2;
yy2 -= size/2;
xx1 -= 10;
xx2 -= 10;
}
}
}else {
if(Math.abs(xx1-xx2)>Math.abs(yy1-yy2)) {
xx2 = xx2+size/2;
xx1 = xx1-size/2;
yy1 += 10;
yy2 += 10;
}else {
if(yy1>yy2) {
yy2 += size/2;
yy1 -= size/2;
xx1 -= 10;
xx2 -= 10;
}else {
yy1 += size/2;
yy2 -= size/2;
xx1 += 10;
xx2 += 10;
}
}
}
drawALWithNote(xx1, yy1, xx2, yy2, (Graphics2D)g, relation , false);
}
else{
Point begin = drawelement.getDrawlist().get(0).getP1();
Point end = drawelement.getDrawlist().get(1).getP1();
String relation = drawelement.getName();
int xx1 = (int)begin.getX()+size/2;
int yy1 = (int)begin.getY()+size/2;
int xx2 = (int)end.getX()+size/2;
int yy2 = (int)end.getY()+size/2;
if(xx1 < xx2) {
if(Math.abs(xx1-xx2)>Math.abs(yy1-yy2)) {
xx1 = xx1+size/2;
xx2 = xx2-size/2;
}else {
if(yy1>yy2) {
yy2 += size/2;
yy1 -= size/2;
}else {
yy1 += size/2;
yy2 -= size/2;
}
}
}else {
if(Math.abs(xx1-xx2)>Math.abs(yy1-yy2)) {
xx2 = xx2+size/2;
xx1 = xx1-size/2;
}else {
if(yy1>yy2) {
yy2 += size/2;
yy1 -= size/2;
}else {
yy1 += size/2;
yy2 -= size/2;
}
}
}
drawALWithNote(xx1, yy1, xx2, yy2, (Graphics2D)g, relation , true);//字在线段上方
}
}
hasPaintedElementArrayList.add(drawelement); // 将已经重绘的图案或线段存储到已画列表中
}
}
public ArrayList<DrawElement> getDrawlist() {
return drawlist;
}
public void setDrawlist(ArrayList<DrawElement> drawlist) {
this.drawlist = drawlist;
}
public boolean isReverseInDrawlist(DrawElement drawelement,ArrayList<DrawElement> drawElementList){
// 判断drawelement线段被反向以后是不是在列表中已存在为了存在的时候反向箭头画图要向下偏移一点
for(DrawElement drawEleInDrawlist:drawElementList) {
if(drawEleInDrawlist.getType() == 2){
Point drawEleInDrawlistBegin = drawEleInDrawlist.getDrawlist().get(0).getP1();
Point drawEleInDrawlistEnd = drawEleInDrawlist.getDrawlist().get(1).getP1();
Point drawEleBegin = drawelement.getDrawlist().get(0).getP1();
Point drawEleEnd = drawelement.getDrawlist().get(1).getP1();
if ((drawEleInDrawlistBegin==drawEleEnd)&&( drawEleInDrawlistEnd==drawEleBegin)){
return true;
}
}
}
return false;
}
public static void saveDrawList(String pathname, ArrayList<DrawElement> drawElementList) {
try {
File writeName = new File(pathname);
writeName.createNewFile(); // 创建新文件,有同名的文件的话直接覆盖
try (FileWriter writer = new FileWriter(writeName);
BufferedWriter out = new BufferedWriter(writer)
) {
// 下面是将drawElementList写入文件中
String splitStr = "$";
String writeStr = "";
for(DrawElement drawEleInDrawlist:drawElementList) {
if (drawEleInDrawlist.getType()==1){ // 将图案写入文件
writeStr = "1" + splitStr + drawEleInDrawlist.getName() + splitStr + drawEleInDrawlist.getPath() + splitStr + drawEleInDrawlist.getFilename()
+ splitStr + (int) drawEleInDrawlist.getP1().getX() + splitStr + (int) drawEleInDrawlist.getP1().getY()
+ splitStr + drawEleInDrawlist.getSpecificType()+"\r\n";
out.write(writeStr);
}else if (drawEleInDrawlist.getType()==2) { //将线段写入文件
writeStr = "2" + splitStr + drawEleInDrawlist.getName()
+ splitStr + (int) drawEleInDrawlist.getDrawlist().get(0).getP1().getX()
+ splitStr + (int) drawEleInDrawlist.getDrawlist().get(0).getP1().getY()
+ splitStr + (int) drawEleInDrawlist.getDrawlist().get(1).getP1().getX()
+ splitStr + (int) drawEleInDrawlist.getDrawlist().get(1).getP1().getY()
+"\r\n";
out.write(writeStr);
}else {
System.out.println("No such type of the drawlist.");
}
}
out.flush(); // 把缓存区内容压入文件
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static ArrayList<DrawElement> readDrawList(String pathname) {
ArrayList<DrawElement> drawElementList = new ArrayList<DrawElement>();
List<String> drawElementStrList = ReadTxt.readFile(pathname);
for (String drawElementStr : drawElementStrList) { // drawElementStr是一个drawElement转成字符串后的形式在循环体中对每个drawElement进行还原并保存到列表中
String[] drawElementSplit = drawElementStr.split("\\$");
if (drawElementSplit[0].equals("1")){ // 第一个字符是1表示解析的是图案
DrawElement tempDrawElement = new DrawElement(drawElementSplit[1], drawElementSplit[2], new Point(Integer.parseInt(drawElementSplit[4]), Integer.parseInt(drawElementSplit[5])), drawElementSplit[3]);
tempDrawElement.setSpecificType(drawElementSplit[6]);
tempDrawElement.setType(1);
drawElementList.add(tempDrawElement);
}else if (drawElementSplit[0].equals("2")) { // 解析的是带箭头的线段
DrawElement tempBeginDrawElement = new DrawElement("", "", new Point(Integer.parseInt(drawElementSplit[2]), Integer.parseInt(drawElementSplit[3])), "");
DrawElement tempEndDrawElement = new DrawElement("", "", new Point(Integer.parseInt(drawElementSplit[4]), Integer.parseInt(drawElementSplit[5])), "");
for (DrawElement drawEle : drawElementList) { // 必须要在drawElementList中找到线段的起始和结束图案这样才是有效的
if (drawEle.getType()==1){ // 只在图案中寻找
if (((int) drawEle.getP1().getX() == Integer.parseInt(drawElementSplit[2])) && ((int) drawEle.getP1().getY() == Integer.parseInt(drawElementSplit[3]))){
tempBeginDrawElement = drawEle;
}
if (((int) drawEle.getP1().getX() == Integer.parseInt(drawElementSplit[4])) && ((int) drawEle.getP1().getY() == Integer.parseInt(drawElementSplit[5]))) {
tempEndDrawElement = drawEle;
}
}
}
DrawElement tempDrawElement = new DrawElement(tempBeginDrawElement, tempEndDrawElement);
tempDrawElement.setName(drawElementSplit[1]);
tempDrawElement.setType(2);
drawElementList.add(tempDrawElement);
}else {
System.out.print("error in readDrawList: ");
System.out.println(drawElementSplit);
}
}
return drawElementList;
}
}

@ -0,0 +1,288 @@
package CodeGenerator;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.image.ImageObserver;
import java.io.File;
import java.io.FileFilter;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import com.sun.xml.internal.ws.org.objectweb.asm.Label;
public class MyGramJPanel extends JFrame{
private int x=-220;
private int y=10;
private int maxlen = 0;
public MyGramJPanel(String filepath) {
super();
this.setLayout(null);
//this.setPreferredSize(new Dimension(200,200));
List<Class> clazzs = new ArrayList<Class>();
File file = new File(filepath);
String filepath2 = file.getAbsolutePath().replaceAll("src", "bin"); // 注意路径上的文件夹及项目名称中不能出现src
String packageName = file.getName();
if(packageName.equals("src")) {
packageName = "";
}
this.setTitle(packageName);
MyGramJPanel.findClassInPackageByFile(filepath2,true,clazzs);
// 写入要生成的txt文件
writeClassDiagramTxt("ClassDiagram.txt", "@startuml\r\n", false);
for(Class c:clazzs) {
this.my_addClass(c);
}
writeClassDiagramTxt("ClassDiagram.txt", "@enduml", true);
// 根据txt文件生成png格式的类图
String resource_path = this.getClass().getResource("").getPath();
resource_path = resource_path.substring(1, resource_path.length());
generate_class_diagram_from_txt(
resource_path + "plantuml.jar",
resource_path + "ClassDiagram.txt"
); // 生成的ClassDiagram.png文件和txt文件在同一个文件夹
// 显示生成的类图
ImageIcon icon = new ImageIcon(this.getClass().getResource("").getPath() + "ClassDiagram.png");
JLabel image_label = new JLabel(icon);
image_label.setBounds(20, 20, icon.getIconWidth(), icon.getIconHeight()); //设置标签的大小位置
this.add(image_label);
this.setSize(icon.getIconWidth()+50, icon.getIconHeight()+70);
this.setResizable(false);
}
public void writeClassDiagramTxt(String filename,String text, boolean append){
/*
* append
*/
if (append){
ReadTxt.writeFileByAppending(this.getClass().getResource("").getPath() + filename, text);
}else {
ReadTxt.writeFile(this.getClass().getResource("").getPath() + filename, text);
}
}
public static void generate_class_diagram_from_txt(String jar_package_path, String txt_path) {
Runtime run = Runtime.getRuntime();
try {
String command = "java -jar " + jar_package_path + " " + txt_path;
Process process = run.exec(command);
InputStream in = process.getInputStream();
while (in.read() != -1) {
System.out.println(in.read());
}
in.close();
process.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
}
public void my_addClass(Class clazz) {
Clazzs c = getClazzs(clazz);
if(c == null) {
return;
}
String class_configuration = "class " + c.getName() + " {\r\n";
for(String s:c.getFields()) {
class_configuration = class_configuration + s + "\r\n";
}
for(String s:c.getMethods()) {
class_configuration = class_configuration + s + "\r\n";
}
class_configuration = class_configuration + "}\r\n";
class_configuration = class_configuration + c.getParentClassName() + " <|-- " + c.getName() + "\r\n"; // 添加继承信息
writeClassDiagramTxt("ClassDiagram.txt", class_configuration, true);
}
public void addClass(Class clazz) {
Clazzs c = getClazzs(clazz);
if(c == null) {
return;
}
JInternalFrame internaljframe = new JInternalFrame();
internaljframe.setLayout(new GridLayout(1,1));
JTextArea text = new JTextArea();
text.setBackground(new Color(254,254,200));
text.setEditable(false);
text.setName(c.getFile().getAbsolutePath());
String title = c.getName();
for(int i = 0;i<(28-c.getName().length())/2;i++) {
title = " " + title;
}
text.append(title+"\n");
text.append(" <Java Class>"+"\n");
//text.append(c.getName()+"\n"+"<Java Class>"+"\n");
text.append("----------------------------------------------------------------------"+"\n");
for(String s:c.getFields()) {
text.append(s+"\n");
}
text.append("----------------------------------------------------------------------"+"\n");
for(String s:c.getMethods()) {
text.append(s+"\n");
}
internaljframe.add(text);
int len = (c.getFields().size() + c.getMethods().size()+4)*17;
internaljframe.setSize(220, len);
if((x+380) >= 800) {
x=-220;
y=y+maxlen+25;
maxlen = 0;
}
maxlen = maxlen>len?maxlen:len;
internaljframe.setLocation((x=x+230), y);
internaljframe.setBackground(new Color(254,254,200));
internaljframe.setBorder(null);
internaljframe.setFrameIcon(null);
//internaljframe.setBackground(Color.white);
//internaljframe.setOpaque(false);
//internaljframe.toFront();
this.add(internaljframe);
internaljframe.setVisible(true);
}
public Clazzs getClazzs(Class clazz) {
Clazzs c = new Clazzs();
if(clazz != null) {
c.setName(clazz.getSimpleName());
c.setParentClassName(clazz.getSuperclass().getName());
Field[] fields = clazz.getDeclaredFields();
for(Field f : fields) {
String fie = f.getModifiers()%2==1?"+":"-";
fie = fie+" "+f.getName()+" : "+f.getType().getSimpleName();
/*if(fie.length()>24) {
StringBuilder sb = new StringBuilder(fie);//构造一个StringBuilder对象
sb.insert(24, "\n ");//在指定的位置1插入指定的字符串
fie = sb.toString();
}*/
c.getFields().add(fie);
}
Method[] methods = clazz.getDeclaredMethods();
for(Method m : methods) {
String meth = m.getModifiers()%2==1?"+":"-";
meth = meth+" "+m.getName()+"() : "+m.getReturnType().getSimpleName();
/*if(meth.length()>24) {
StringBuilder sb = new StringBuilder(meth);//构造一个StringBuilder对象
sb.insert(24, "\n ");//在指定的位置1插入指定的字符串
meth = sb.toString();
}*/
c.getMethods().add(meth);
}
String str1 = clazz.getResource("").toString();
String str2 = clazz.getSimpleName();
String str3 = str1.replaceAll("bin", "src");
String str4 = "/" + str3.substring(6)+str2+".java";
File file = new File(str4);
if(!file.exists()) {
return null;
}else {
c.setFile(file);
}
}
return c;
}
public static void findClassInPackageByFile(String filePath, final boolean recursive, List<Class> clazzs) {
/*
* filePathjavaClass
*/
filePath = filePath.replaceAll("\\\\", "\\\\\\\\"); // java中要将单反斜杠换成双反斜杠
filePath = filePath.replaceAll("java", "class");
File dir = new File(filePath);
if (!dir.exists()) {
return;
}
// 在给定的目录下找到所有的文件,并且进行条件过滤
File[] dirFiles = dir.listFiles(new FileFilter() {
public boolean accept(File file) {
boolean acceptDir = recursive && file.isDirectory();//接受dir目录
boolean acceptClass = file.getName().endsWith("class");//接受class文件
return acceptDir || acceptClass;
}
});
// 列表为空说明被点击的只是一个文件
if(dirFiles == null){
String className = dir.getName().substring(0, dir.getName().length() - 6);
try {
String filepath = dir.getAbsolutePath();
int index = filepath.indexOf("bin")+4;
int end = filepath.length()-className.length()-7;
String packageName = "";
if(index <= end) {
packageName = filepath.substring(index ,end );
packageName = packageName.replace('\\', '.');
}
String str = packageName.equals("")?className:(packageName + "." + className);
//clazzs.add(Thread.currentThread().getContextClassLoader().loadClass(str));
clazzs.add(Class.forName(str));
} catch (Exception e) {
e.printStackTrace();
}
return;
}
// 这里处理被右键项是一个文件夹的情况
for (File file : dirFiles) {
if (file.isDirectory()) {
findClassInPackageByFile(file.getAbsolutePath(), recursive, clazzs);
} else {
String className = file.getName().substring(0, file.getName().length() - 6);
try {
String filepath = file.getAbsolutePath();
int index = filepath.indexOf("bin")+4;
int end = filepath.length()-className.length()-7;
String packageName = "";
if(index <= end) {
packageName = filepath.substring(index ,end );
packageName = packageName.replace('\\', '.');
}
String str = packageName.equals("")?className:(packageName + "." + className);
//clazzs.add(Thread.currentThread().getContextClassLoader().loadClass(str));
clazzs.add(Class.forName(str));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
/*
@Override
public void paint(Graphics g) {
// TODO 自动生成的方法存根
super.paint(g);
ImageIcon icon = new ImageIcon(this.getClass().getResource("").getPath() + "ClassDiagram.png");
g.drawImage(icon.getImage(), 30, 50, icon.getIconWidth(), icon.getIconHeight(), null);
this.setSize(icon.getIconWidth()+60, icon.getIconHeight()+80);
}
*/
}

@ -0,0 +1,137 @@
package CodeGenerator;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
public class NewApplication extends JPanel {
private JTextField newApplicationName;
private JTextField newApplicationPath;
private JDialog newApplicationDialog;
private JFileChooser newChooser;
private boolean ok;
private JButton newApplicationButton;
private String path;
private String name;
/**
* Create the panel.
*/
public NewApplication() {
setBounds(100,100,450,130);
setLayout(null);
JLabel lblName = new JLabel("Name:");
lblName.setBounds(37, 22, 50, 16);
add(lblName);
newChooser = new JFileChooser();
newApplicationName = new JTextField();
newApplicationName.setBounds(89, 17, 317, 26);
add(newApplicationName);
newApplicationName.setColumns(10);
newApplicationPath = new JTextField();
newApplicationPath.setBounds(89, 55, 280, 26);
add(newApplicationPath);
newApplicationPath.setColumns(10);
JButton openApplicationPathButton = new JButton("...");
openApplicationPathButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
newChooser.setCurrentDirectory(new File("."));
newChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
newChooser.setDialogTitle("Choose Application Location");
int result = newChooser.showOpenDialog(NewApplication.this);
if (result == JFileChooser.APPROVE_OPTION)
{
path = newChooser.getSelectedFile().getPath();
newApplicationPath.setText(path);
}
}
});
openApplicationPathButton.setBounds(375, 55, 30, 25);
add(openApplicationPathButton);
JLabel lblPath = new JLabel("Path:");
lblPath.setBounds(46, 60, 50, 16);
add(lblPath);
JButton newApplicationButton = new JButton("Create");
newApplicationButton.setBounds(180, 93, 110, 29);
add(newApplicationButton);
newApplicationButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
ok = true;
newApplicationDialog.setVisible(false);
}
});
JButton cancelNewButton = new JButton("Cancel");
cancelNewButton.setBounds(295, 93, 110, 29);
add(cancelNewButton);
cancelNewButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
newApplicationDialog.setVisible(false);
}
});
}
public String newApplicationName()
{
name = newApplicationName.getText();
return name;
}
public String newApplicationPath()
{
return path;
}
public boolean showDialog(Component parent, String title)
{
ok = false;
Frame owner = null;
if (parent instanceof Frame) owner = (Frame) parent;
else owner = (Frame) SwingUtilities.getAncestorOfClass(Frame.class, parent);
if (newApplicationDialog == null || newApplicationDialog.getOwner() != owner)
{
newApplicationDialog = new JDialog(owner, true);
newApplicationDialog.getContentPane().add(this);
newApplicationDialog.getRootPane().setDefaultButton(newApplicationButton);
newApplicationDialog.pack();
}
newApplicationDialog.setTitle(title);
newApplicationDialog.setBounds(300, 300, 470, 180);
newApplicationDialog.setVisible(true);
return ok;
}
}

@ -0,0 +1,67 @@
package CodeGenerator;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Locale;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
public class OpenApplication extends JPanel {
private JFileChooser openChooser;
private boolean ok;
private String path;
/**
* Create the panel.
*/
public OpenApplication() {
setBounds(100,100,450,130);
setLayout(null);
UIManager.put("FileChooser.cancelButtonText", "Cancel"); //修改取消
UIManager.put("FileChooser.saveButtonText", "Save"); //修改保存
UIManager.put("FileChooser.openButtonText", "Import");//修改打开
openChooser = new JFileChooser();
openChooser.setCurrentDirectory(new File("."));
openChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
openChooser.setDialogTitle("Choose Application Location");
int result = openChooser.showOpenDialog(OpenApplication.this);
if (result == JFileChooser.APPROVE_OPTION)
{
path = openChooser.getSelectedFile().getPath();
ok = true;
}
}
public String openApplicationPath()
{
return path;
}
public boolean showDialog(Component parent, String title)
{
return ok;
}
}

@ -0,0 +1,109 @@
package CodeGenerator;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import CodeGenerator.DrawElement;
import CodeGenerator.MyCanvas;
public class PddlJFrame extends JFrame implements ActionListener {
public JTextField textfield;
private JButton createPlanningNodeButton;
private DrawElement drawelement;
private MyCanvas cans;
String mypath = "";
private JComboBox <String> comboBoxPlanningType;
public PddlJFrame(String path,DrawElement drawelement,MyCanvas cans) {
super("Planning Create");
this.mypath = path;
this.drawelement = drawelement;
this.cans = cans;
this.setLayout(null);
this.setBounds(300, 300, 450, 180);
JLabel lblPlanningNodeName = new JLabel("Planning Node name:");
lblPlanningNodeName.setBounds(40, 24, 154, 16);
this.add(lblPlanningNodeName);
textfield = new JTextField();
textfield.setBounds(206, 19, 217, 26);
this.add(textfield);
textfield.setColumns(10);
JLabel lblPlanningType = new JLabel("Planning Node Type:");
lblPlanningType.setBounds(40, 63, 154, 16);
this.add(lblPlanningType);
comboBoxPlanningType = new JComboBox();
comboBoxPlanningType.setBounds(206, 59, 217, 27);
this.add(comboBoxPlanningType);
comboBoxPlanningType.addItem("Domain Description");
comboBoxPlanningType.addItem("Problem Description");
createPlanningNodeButton = new JButton("Create Planning Node");
//createAgentButton.setBounds(177, 130, 117, 29);
createPlanningNodeButton.setBounds(230, 98, 193, 29);
this.add(createPlanningNodeButton);
createPlanningNodeButton.addActionListener(this);
createPlanningNodeButton.addActionListener(this);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
MyCanvas tempCans = cans; // 必须创建这两个局部变量才能在下面的windowClosing事件中访问到
DrawElement tempDrawElement = drawelement;
this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); // 捕捉关闭窗口事件
this.addWindowListener(new WindowAdapter() { // 捕捉到窗口关闭事件
public void windowClosing(WindowEvent e) {
/*
*code for example:
int i=JOptionPane.showConfirmDialog(null, "确定要退出系统吗?", "退出系统", JOptionPane.YES_NO_OPTION);
if(i==JOptionPane.YES_OPTION){
System.exit(0);
}
*/
// 如果未按下选择关系的按钮退出,而是选择按右上角的关闭对话框按钮,会触发该事件
// 触发该事件后我们要将之前已经添加到drawlist中的templist删除
tempCans.removeIcon(tempDrawElement);
dispose();
}
});
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == this.createPlanningNodeButton) {
String name = this.textfield.getText();
String type = (String)this.comboBoxPlanningType.getSelectedItem();
if(name!=null&&!name.equals("")) {
drawelement.setName(name);
}
//FileUtils.createFile(mypath, drawelement.getName()+".pddl");
if (type == "Domain Description")
{
DomainDescriptionGeneratorClient.PDDLFileGenerator(mypath, name);
}
else
{
ProblemDescriptionGeneratorClient.PDDLFileGenerator(mypath, name);
}
drawelement.setFilename("//PDDL Files//"+drawelement.getName()+".pddl");
MyCanvas.saveDrawList(this.mypath +"/.arcgprj", this.cans.getDrawlist());
cans.repaint();
ReadTxt.writeFile(this .getClass().getResource( "" ).getPath() + "Modified.ini", "1"); // 写入1通知刷新
this.dispose();
}
}
}

@ -0,0 +1,39 @@
package SampleApplication.Agent;
import SampleApplication.AgentConfiguration;
import agentBehaviourPrototype.ExecutionBehaviour;
import agentBehaviourPrototype.ReceiveDataFromAgentBehaviour;
import agentBehaviourPrototype.SendDataToAgentBehaviour;
import agentEntityPrototype.RobotAgent;
import edu.wpi.rail.jrosbridge.services.std.Empty.Request;
import jade.core.AID;
public class ${entity.className}<#if entity.superclass?has_content> extends ${entity.superclass} </#if>
{
Request planRequest = new Request();
Request problemGeRequest = new Request();
<#list entity.allRelatedElements as allReEle>
private AID ${allReEle.specificType} = new AID(AgentConfiguration.${allReEle.specificType}ID, false);
</#list>
protected void setup() {
//automatically generated
this.controller.addService(AgentConfiguration.problemGenerationServiceName, AgentConfiguration.problemGenerationServiceType);
this.controller.addService(AgentConfiguration.problemGenerationServiceName, AgentConfiguration.problemGenerationServiceType);
this.controller.getService(AgentConfiguration.problemGenerationServiceName).callServiceAndWait(problemGeRequest);
this.controller.getService(AgentConfiguration.problemGenerationServiceName).callServiceAndWait(planRequest);
//agent communication
<#list entity.postiveRelatedElementsWithRelation as posReEleWithRela>
this.behList.addElement(new SendDataToAgentBehaviour(this, controller, ${posReEleWithRela.specificType}, AgentConfiguration.${posReEleWithRela.relation}DataKey));
</#list>
<#list entity.negativeRelatedElementsWithRelation as negReEleWithRela>
this.behList.addElement(new ReceiveDataFromAgentBehaviour(this, controller, ${negReEleWithRela.specificType}, AgentConfiguration.${negReEleWithRela.relation}DataKey));
</#list>
addBehaviour(tbf.wrap(new ExecutionBehaviour(this, ds, this.behList)));
}
}

@ -0,0 +1,192 @@
package CodeGenerator;
import java.awt.Canvas;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class PlannerAgentCodeGeneratorClient {
private static File javaFile = null;
public static void AgentFileGenerator(String path, DrawElement drawelement, MyCanvas cans) {
Configuration cfg = new Configuration();
try {
// 指定模板文件从何处加载的数据源,这里设置一个文件目录
cfg.setDirectoryForTemplateLoading(new File("./src/CodeGenerator"));
cfg.setObjectWrapper(new DefaultObjectWrapper());
// 获取模板文件
Template template = cfg.getTemplate("PlannerAgent.ftl");
// 创建数据模型
Map<String, Object> root = createDataModel(path, drawelement, cans);
// 合并模板和数据模型
// 创建.java类文件
if(javaFile != null){
Writer javaWriter = new FileWriter(javaFile);
template.process(root, javaWriter);
javaWriter.flush();
System.out.println("文件生成路径:" + javaFile.getCanonicalPath());
javaWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
}
//创建数据模型
private static Map<String, Object> createDataModel(String path, DrawElement drawelement, MyCanvas cans) {
Map<String, Object> root = new HashMap<String, Object>();
Entity user = new Entity();
TbfEntity user1 = new TbfEntity();
ControllerEntity user2 = new ControllerEntity();
//user.setJavaPackage("agent"); // 创建包名
user.setClassName(drawelement.getName()); // 创建类名
user.setConstructors(false); // 是否创建构造函数
user.setSuperclass("RobotAgent");//创建父类
user.setSpecificType(drawelement.getSpecificType());
List<Property> propertyList = new ArrayList<Property>();
List<TbfEntity> tbfEntityList = new ArrayList<TbfEntity>();
List<Entity> entityList = new ArrayList<Entity>();
List<ControllerEntity> controllerEntityList = new ArrayList<ControllerEntity>();
List<DrawElementWithRelation> postiveRelatedElementsWithRelation = new ArrayList<DrawElementWithRelation>();
List<DrawElementWithRelation> negativeRelatedElementsWithRelation = new ArrayList<DrawElementWithRelation>();
List<DrawElement> allRelatedElements = new ArrayList<DrawElement>();
// 创建实体属性
Property attribute1 = new Property();
attribute1.setJavaType("static final long");
attribute1.setPropertyName("serialVersionUID");
attribute1.setPropertyType(PropertyType.Long);
// 创建实体属性(tbf)
int tbfAmount = 4; //这里输入tbf的数量
for (int i = 1; i < tbfAmount +1 ; i = i + 1) {
String tbfName = "tbf" + i;
TbfEntity tbfEntityAttribute = new TbfEntity();
tbfEntityAttribute.setClassName(tbfName);
tbfEntityAttribute.setSuperclass("ThreadedBehaviourFactory");
tbfEntityList.add(tbfEntityAttribute);
}
//TbfEntity tbfEntityAttribute2 = new TbfEntity();
//tbfEntityAttribute2.setClassName("tbf2");
//tbfEntityAttribute2.setSuperclass("ThreadedBehaviourFactory");
//创建实体属性(controller)
ControllerEntity controllerAttribute = new ControllerEntity();
controllerAttribute.setClassName("moveController");
controllerAttribute.setSuperclass("Controller");
//创建实体属性(除tbf和controller以外的属性)
Entity entityAttribute1 = new Entity();
entityAttribute1.setClassName("cameraAgent");
entityAttribute1.setSuperclass("AID");
Entity entityAttribute2 = new Entity();
entityAttribute2.setClassName("bumperAgent");
entityAttribute2.setSuperclass("AID");
Entity entityAttribute3 = new Entity();
entityAttribute3.setClassName("ds");
entityAttribute3.setSuperclass("DataStore");
propertyList.add(attribute1);
//tbfEntityList.add(tbfEntityAttribute1);
//tbfEntityList.add(tbfEntityAttribute2);
controllerEntityList.add(controllerAttribute);
entityList.add(entityAttribute1);
entityList.add(entityAttribute2);
entityList.add(entityAttribute3);
// 判断该元素是否和其他元素有箭头关系
for(DrawElement drawEleInDrawlist:cans.getDrawlist()) {
if(drawEleInDrawlist.getType() == 2){ // 是箭头线段的时候要判断是否和该元素有关
if (drawelement.getName() == drawEleInDrawlist.getDrawlist().get(0).getName()){ // 该元素是箭头线段的起始点(因为名字唯一,所以名字相同就判定为两个图案是同一对象)
allRelatedElements.add(drawEleInDrawlist.getDrawlist().get(1)); //列表中存储的是箭头线段的结束点
postiveRelatedElementsWithRelation.add(new DrawElementWithRelation(drawEleInDrawlist.getDrawlist().get(1), drawEleInDrawlist.getName()));
}
else if (drawelement.getName() == drawEleInDrawlist.getDrawlist().get(1).getName()) { // 该元素是箭头线段的结束点
allRelatedElements.add(drawEleInDrawlist.getDrawlist().get(0));
negativeRelatedElementsWithRelation.add(new DrawElementWithRelation(drawEleInDrawlist.getDrawlist().get(0), drawEleInDrawlist.getName()));
}
else{}
}
}
// 将有关系的对象放到同一个列表中但不能重复为了后续生成的文件中获取交互对象id的那一行用
removeDuplicate(allRelatedElements);
// 将属性集合添加到实体对象中
user.setProperties(propertyList);
user.setEntities(entityList);
user.setPostiveRelatedElementsWithRelation(postiveRelatedElementsWithRelation); // 箭头线段的起始点在该对象
user.setNegativeRelatedElementsWithRelation(negativeRelatedElementsWithRelation); // 箭头线段的结束点在该对象
user.setAllRelatedElements(allRelatedElements); // 和该对象用箭头相关的所有对象都在该列表中
user1.setTbfentities(tbfEntityList);
user2.setControllerentities(controllerEntityList);
// 创建.java类文件
File outDirFile = new File(path + "/Agent"); // .java类文件存放的文件夹
if(!outDirFile.exists()){
outDirFile.mkdir();
}
javaFile = toJavaFilename(outDirFile, user.getClassName());
root.put("entity", user);
root.put("tbfentity",user1);
root.put("controllerentity", user2);
return root;
}
/**
* .java .javaFile
* @param outDirFile
* @param javaPackage java
* @param javaClassName java
* @return
*/
private static File toJavaFilename(File outDirFile, String javaClassName) {
File file = new File(outDirFile, javaClassName + ".java");
return file;
}
// 删除ArrayList中重复元素
public static void removeDuplicate(List<DrawElement> list) {
for (int i = 0; i < list.size() - 1; i++) {
for (int j = list.size() - 1; j > i; j--) {
if (list.get(j).equals(list.get(i))) {
list.remove(j);
}
}
}
}
}

@ -0,0 +1,36 @@
(define (${entity.className})
(:domain
)
(:requirements
)
(:types
)
(:predicates
)
(:objects
)
(:init
)
(:goal
)
(:durative-action
:parameters ()
:duration ()
:condition ()
:effect ()
)
(:action
:parameters ()
:precondition ()
:effect ()
:observe ()
)

@ -0,0 +1,110 @@
package CodeGenerator;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class PlanningNodeCodeGeneratorClient {
private static File pddlFile = null;
public static void PDDLFileGenerator(String path, String pddlName) {
Configuration cfg = new Configuration();
try {
// 指定模板文件从何处加载的数据源,这里设置一个文件目录
cfg.setDirectoryForTemplateLoading(new File("./src/CodeGenerator"));
cfg.setObjectWrapper(new DefaultObjectWrapper());
// 获取模板文件
Template template = cfg.getTemplate("PlanningNode.ftl");
// 创建数据模型
Map<String, Object> root = createDataModel(path, pddlName);
// 合并模板和数据模型
// 创建.pddl类文件
if(pddlFile != null){
Writer pddlWriter = new FileWriter(pddlFile);
template.process(root, pddlWriter);
pddlWriter.flush();
System.out.println("文件生成路径:" + pddlFile.getCanonicalPath());
pddlWriter.close();
}
// 输出到Console控制台
/*
Writer out = new OutputStreamWriter(System.out);
template.process(root, out);
out.flush();
out.close();
*/
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
}
//创建数据模型
private static Map<String, Object> createDataModel(String path, String pddlName) {
Map<String, Object> root = new HashMap<String, Object>();
Entity user = new Entity();
//TbfEntity user1 = new TbfEntity();
//ControllerEntity user2 = new ControllerEntity();
//user.setJavaPackage("agent"); // 创建包名
user.setClassName(pddlName); // 创建类名
user.setConstructors(false); // 是否创建构造函数
//user.setSuperclass("Agent");//创建父类
List<Property> propertyList = new ArrayList<Property>();
List<Entity> entityList = new ArrayList<Entity>();
// 创建实体属性
Property attribute1 = new Property();
attribute1.setJavaType("static final long");
attribute1.setPropertyName("serialVersionUID");
attribute1.setPropertyType(PropertyType.Long);
// 将属性集合添加到实体对象中
user.setProperties(propertyList);
user.setEntities(entityList);
// 创建.pddl类文件
File outDirFile = new File(path + "/PDDL Files");
if(!outDirFile.exists()){
outDirFile.mkdir();
}
//javaFile = toJavaFilename(outDirFile, user.getJavaPackage(), user.getClassName());
pddlFile = toPddlFilename(outDirFile, user.getClassName());
root.put("entity", user);
return root;
}
/**
* .pddl .pddlFile
* @param outDirFile
* @param javaPackage java
* @param javaClassName java
* @return
*/
private static File toPddlFilename(File outDirFile, String pddlName) {
File file = new File(outDirFile, pddlName + ".pddl");
return file;
}
}

@ -0,0 +1,75 @@
package CodeGenerator;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JComboBox;
public class PlanningNodeGeneratorDialog extends JFrame implements ActionListener {
public JTextField textfield;
private JButton createPlanningNodeButton;
String mypath;
private JComboBox <String> comboBoxPlanningType;
/**
* Create the panel.
*/
public PlanningNodeGeneratorDialog(String path) {
super("Planning Create");
this.mypath = path;
this.setLayout(null);
this.setBounds(300, 300, 450, 180);
JLabel lblPlanningNodeName = new JLabel("Planning Node name:");
lblPlanningNodeName.setBounds(60, 24, 134, 16);
this.add(lblPlanningNodeName);
textfield = new JTextField();
textfield.setBounds(206, 19, 217, 26);
this.add(textfield);
textfield.setColumns(10);
JLabel lblPlanningType = new JLabel("Planning Node Type:");
lblPlanningType.setBounds(123, 63, 75, 16);
this.add(lblPlanningType);
comboBoxPlanningType = new JComboBox();
comboBoxPlanningType.setBounds(206, 59, 217, 27);
this.add(comboBoxPlanningType);
comboBoxPlanningType.addItem("Domain Description");
comboBoxPlanningType.addItem("Problem Description");
createPlanningNodeButton = new JButton("Create Planning Node");
//createAgentButton.setBounds(177, 130, 117, 29);
createPlanningNodeButton.setBounds(260, 98, 163, 29);
this.add(createPlanningNodeButton);
createPlanningNodeButton.addActionListener(this);
createPlanningNodeButton.addActionListener(this);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == this.createPlanningNodeButton) {
String name = this.textfield.getText();
String type = (String)this.comboBoxPlanningType.getSelectedItem();
if (type == "Domain Description")
{
DomainDescriptionGeneratorClient.PDDLFileGenerator(mypath, name);
}
else
{
ProblemDescriptionGeneratorClient.PDDLFileGenerator(mypath, name);
}
this.dispose();
}
}
}

@ -0,0 +1,15 @@
(define (${entity.className})
(:domain )
(:objects
)
(:init
)
(:goal
)

@ -0,0 +1,110 @@
package CodeGenerator;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class ProblemDescriptionGeneratorClient {
private static File pddlFile = null;
public static void PDDLFileGenerator(String path, String pddlName) {
Configuration cfg = new Configuration();
try {
// 指定模板文件从何处加载的数据源,这里设置一个文件目录
cfg.setDirectoryForTemplateLoading(new File("./src/CodeGenerator"));
cfg.setObjectWrapper(new DefaultObjectWrapper());
// 获取模板文件
Template template = cfg.getTemplate("ProblemDescription.ftl");
// 创建数据模型
Map<String, Object> root = createDataModel(path, pddlName);
// 合并模板和数据模型
// 创建.pddl类文件
if(pddlFile != null){
Writer pddlWriter = new FileWriter(pddlFile);
template.process(root, pddlWriter);
pddlWriter.flush();
System.out.println("文件生成路径:" + pddlFile.getCanonicalPath());
pddlWriter.close();
}
// 输出到Console控制台
/*
Writer out = new OutputStreamWriter(System.out);
template.process(root, out);
out.flush();
out.close();
*/
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
}
//创建数据模型
private static Map<String, Object> createDataModel(String path, String pddlName) {
Map<String, Object> root = new HashMap<String, Object>();
Entity user = new Entity();
//TbfEntity user1 = new TbfEntity();
//ControllerEntity user2 = new ControllerEntity();
//user.setJavaPackage("agent"); // 创建包名
user.setClassName(pddlName); // 创建类名
user.setConstructors(false); // 是否创建构造函数
//user.setSuperclass("Agent");//创建父类
List<Property> propertyList = new ArrayList<Property>();
List<Entity> entityList = new ArrayList<Entity>();
// 创建实体属性
Property attribute1 = new Property();
attribute1.setJavaType("static final long");
attribute1.setPropertyName("serialVersionUID");
attribute1.setPropertyType(PropertyType.Long);
// 将属性集合添加到实体对象中
user.setProperties(propertyList);
user.setEntities(entityList);
// 创建.pddl类文件
File outDirFile = new File(path + "/PDDL Files");
if(!outDirFile.exists()){
outDirFile.mkdir();
}
//javaFile = toJavaFilename(outDirFile, user.getJavaPackage(), user.getClassName());
pddlFile = toPddlFilename(outDirFile, user.getClassName());
root.put("entity", user);
return root;
}
/**
* .pddl .pddlFile
* @param outDirFile
* @param javaPackage java
* @param javaClassName java
* @return
*/
private static File toPddlFilename(File outDirFile, String pddlName) {
File file = new File(outDirFile, pddlName + ".pddl");
return file;
}
}

@ -0,0 +1,40 @@
package CodeGenerator;
/**
*
* @author lvzb.software@qq.com
*
*/
public class Property {
// 属性数据类型
private String javaType;
// 属性名称
private String propertyName;
private PropertyType propertyType;
public String getJavaType() {
return javaType;
}
public void setJavaType(String javaType) {
this.javaType = javaType;
}
public String getPropertyName() {
return propertyName;
}
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
public PropertyType getPropertyType() {
return propertyType;
}
public void setPropertyType(PropertyType propertyType) {
this.propertyType = propertyType;
}
}

@ -0,0 +1,9 @@
package CodeGenerator;
/**
*
* @author lvzb.software@qq.com
*
*/
public enum PropertyType {
Byte, Short, Int, Long, Boolean, Float, Double, String, ByteArray, Date
}

@ -0,0 +1,90 @@
package CodeGenerator;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import CodeGenerator.DrawElement;
import CodeGenerator.MyCanvas;
public class PythonJFrame extends JFrame implements ActionListener {
public JTextField textfield;
private JButton createROSNodeButton;
private DrawElement drawelement;
private MyCanvas cans;
String mypath = "";
public PythonJFrame(String path,DrawElement drawelement,MyCanvas cans) {
super("Create ROS Node");
this.mypath = path;
this.drawelement = drawelement;
this.cans = cans;
this.setLayout(null);
this.setBounds(300, 300, 450, 140);
JLabel lblROSNodeName = new JLabel("ROS Node name:");
lblROSNodeName.setBounds(55, 24, 124, 16);
this.add(lblROSNodeName);
textfield = new JTextField();
textfield.setBounds(190, 19, 237, 26);
this.add(textfield);
textfield.setColumns(10);
createROSNodeButton = new JButton("Create ROS Node");
//createAgentButton.setBounds(177, 130, 117, 29);
createROSNodeButton.setBounds(253, 59, 173, 29);
this.add(createROSNodeButton);
createROSNodeButton.addActionListener(this);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
MyCanvas tempCans = cans; // 必须创建这两个局部变量才能在下面的windowClosing事件中访问到
DrawElement tempDrawElement = drawelement;
this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); // 捕捉关闭窗口事件
this.addWindowListener(new WindowAdapter() { // 捕捉到窗口关闭事件
public void windowClosing(WindowEvent e) {
/*
*code for example:
int i=JOptionPane.showConfirmDialog(null, "确定要退出系统吗?", "退出系统", JOptionPane.YES_NO_OPTION);
if(i==JOptionPane.YES_OPTION){
System.exit(0);
}
*/
// 如果未按下选择关系的按钮退出,而是选择按右上角的关闭对话框按钮,会触发该事件
// 触发该事件后我们要将之前已经添加到drawlist中的templist删除
tempCans.removeIcon(tempDrawElement);
dispose();
}
});
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == this.createROSNodeButton) {
String name = this.textfield.getText();
if(name!=null&&!name.equals("")) {
drawelement.setName(name);
}
//FileUtils.createFile(mypath, drawelement.getName()+".python");
ROSNodeCodeGeneratorClient.ROSNodeFileGenerator(mypath, name);
drawelement.setFilename("//Ros Nodes//"+drawelement.getName()+".python");
MyCanvas.saveDrawList(this.mypath +"/.arcgprj", this.cans.getDrawlist());
cans.repaint();
ReadTxt.writeFile(this .getClass().getResource( "" ).getPath() + "Modified.ini", "1"); // 写入1通知刷新
this.dispose();
}
}
}

@ -0,0 +1,142 @@
import rospy
from roslib import message
from sensor_msgs import point_cloud2
from sensor_msgs.msg import PointCloud2
from geometry_msgs.msg import Twist
from math import copysign
class ${entity.className}():
def __init__(self):
rospy.init_node("${entity.className}")
# Set the shutdown function (stop the robot)
rospy.on_shutdown(self.shutdown)
# The dimensions (in meters) of the box in which we will search
# for the person (blob). These are given in camera coordinates
# where x is left/right,y is up/down and z is depth (forward/backward)
self.min_x = rospy.get_param("~min_x", -0.2)
self.max_x = rospy.get_param("~max_x", 0.2)
self.min_y = rospy.get_param("~min_y", -0.3)
self.max_y = rospy.get_param("~max_y", 0.5)
self.max_z = rospy.get_param("~max_z", 1.2)
# The goal distance (in meters) to keep between the robot and the person
self.goal_z = rospy.get_param("~goal_z", 0.6)
# How far away from the goal distance (in meters) before the robot reacts
self.z_threshold = rospy.get_param("~z_threshold", 0.05)
# How far away from being centered (x displacement) on the person
# before the robot reacts
self.x_threshold = rospy.get_param("~x_threshold", 0.05)
# How much do we weight the goal distance (z) when making a movement
self.z_scale = rospy.get_param("~z_scale", 1.0)
# How much do we weight left/right displacement of the person when making a movement
self.x_scale = rospy.get_param("~x_scale", 2.5)
# The maximum rotation speed in radians per second
self.max_angular_speed = rospy.get_param("~max_angular_speed", 2.0)
# The minimum rotation speed in radians per second
self.min_angular_speed = rospy.get_param("~min_angular_speed", 0.0)
# The max linear speed in meters per second
self.max_linear_speed = rospy.get_param("~max_linear_speed", 0.3)
# The minimum linear speed in meters per second
self.min_linear_speed = rospy.get_param("~min_linear_speed", 0.1)
# Slow down factor when stopping
self.slow_down_factor = rospy.get_param("~slow_down_factor", 0.8)
# Initialize the movement command
self.move_cmd = Twist()
# Publisher to control the robot's movement
self.cmd_vel_pub = rospy.Publisher('cmd_vel', Twist, queue_size=5)
# Subscribe to the point cloud
self.depth_subscriber = rospy.Subscriber('point_cloud', PointCloud2, self.set_cmd_vel, queue_size=1)
rospy.loginfo("Subscribing to point cloud...")
# Wait for the pointcloud topic to become available
rospy.wait_for_message('point_cloud', PointCloud2)
rospy.loginfo("Ready to follow!")
def set_cmd_vel(self, msg):
# Initialize the centroid coordinates point count
x = y = z = n = 0
# Read in the x, y, z coordinates of all points in the cloud
for point in point_cloud2.read_points(msg, skip_nans=True):
pt_x = point[0]
pt_y = point[1]
pt_z = point[2]
# Keep only those points within our designated boundaries and sum them up
if -pt_y > self.min_y and -pt_y < self.max_y and pt_x < self.max_x and pt_x > self.min_x and pt_z < self.max_z:
x += pt_x
y += pt_y
z += pt_z
n += 1
# If we have points, compute the centroid coordinates
if n:
x /= n
y /= n
z /= n
# Check our movement thresholds
if (abs(z - self.goal_z) > self.z_threshold):
# Compute the angular component of the movement
linear_speed = (z - self.goal_z) * self.z_scale
# Make sure we meet our min/max specifications
self.move_cmd.linear.x = copysign(max(self.min_linear_speed,
min(self.max_linear_speed, abs(linear_speed))), linear_speed)
else:
self.move_cmd.linear.x *= self.slow_down_factor
if (abs(x) > self.x_threshold):
# Compute the linear component of the movement
angular_speed = -x * self.x_scale
# Make sure we meet our min/max specifications
self.move_cmd.angular.z = copysign(max(self.min_angular_speed,
min(self.max_angular_speed, abs(angular_speed))), angular_speed)
else:
# Stop the rotation smoothly
self.move_cmd.angular.z *= self.slow_down_factor
else:
# Stop the robot smoothly
self.move_cmd.linear.x *= self.slow_down_factor
self.move_cmd.angular.z *= self.slow_down_factor
# Publish the movement command
self.cmd_vel_pub.publish(self.move_cmd)
def shutdown(self):
rospy.loginfo("Stopping the robot...")
# Unregister the subscriber to stop cmd_vel publishing
self.depth_subscriber.unregister()
rospy.sleep(1)
# Send an emtpy Twist message to stop the robot
self.cmd_vel_pub.publish(Twist())
rospy.sleep(1)
if __name__ == '__main__':
try:
${entity.className}()
rospy.spin()
except rospy.ROSInterruptException:
rospy.loginfo("Follower node terminated.")

@ -0,0 +1,110 @@
package CodeGenerator;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class ROSNodeCodeGeneratorClient {
private static File ROSNodeFile = null;
public static void ROSNodeFileGenerator(String path, String ROSNodeName) {
Configuration cfg = new Configuration();
try {
// 指定模板文件从何处加载的数据源,这里设置一个文件目录
cfg.setDirectoryForTemplateLoading(new File("./src/CodeGenerator"));
cfg.setObjectWrapper(new DefaultObjectWrapper());
// 获取模板文件
Template template = cfg.getTemplate("ROSNode.ftl");
// 创建数据模型
Map<String, Object> root = createDataModel(path, ROSNodeName);
// 合并模板和数据模型
// 创建.pddl类文件
if(ROSNodeFile != null){
Writer ROSNodeWriter = new FileWriter(ROSNodeFile);
template.process(root, ROSNodeWriter);
ROSNodeWriter.flush();
System.out.println("文件生成路径:" + ROSNodeFile.getCanonicalPath());
ROSNodeWriter.close();
}
// 输出到Console控制台
/*
Writer out = new OutputStreamWriter(System.out);
template.process(root, out);
out.flush();
out.close();
*/
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
}
//创建数据模型
private static Map<String, Object> createDataModel(String path, String ROSNodeName) {
Map<String, Object> root = new HashMap<String, Object>();
Entity user = new Entity();
//TbfEntity user1 = new TbfEntity();
//ControllerEntity user2 = new ControllerEntity();
//user.setJavaPackage("agent"); // 创建包名
user.setClassName(ROSNodeName); // 创建类名
user.setConstructors(false); // 是否创建构造函数
//user.setSuperclass("Agent");//创建父类
List<Property> propertyList = new ArrayList<Property>();
List<Entity> entityList = new ArrayList<Entity>();
// 创建实体属性
Property attribute1 = new Property();
attribute1.setJavaType("static final long");
attribute1.setPropertyName("serialVersionUID");
attribute1.setPropertyType(PropertyType.Long);
// 将属性集合添加到实体对象中
user.setProperties(propertyList);
user.setEntities(entityList);
// 创建.python类文件
File outDirFile = new File(path + "/Ros Nodes");
if(!outDirFile.exists()){
outDirFile.mkdir();
}
//javaFile = toJavaFilename(outDirFile, user.getJavaPackage(), user.getClassName());
ROSNodeFile = toROSNodeFilename(outDirFile, user.getClassName());
root.put("entity", user);
return root;
}
/**
* .python .pythonFile
* @param outDirFile
* @param javaPackage java
* @param javaClassName java
* @return
*/
private static File toROSNodeFilename(File outDirFile, String ROSNodeName) {
File file = new File(outDirFile, ROSNodeName + ".python");
return file;
}
}

@ -0,0 +1,54 @@
package CodeGenerator;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JComboBox;
public class ROSNodeGeneratorDialog extends JFrame implements ActionListener {
public JTextField textfield;
private JButton createROSNodeButton;
String mypath;
/**
* Create the panel.
*/
public ROSNodeGeneratorDialog(String path) {
super("Create ROS Node");
this.mypath = path;
this.setLayout(null);
this.setBounds(300, 300, 450, 141);
JLabel lblROSNodeName = new JLabel("ROS Node name:");
lblROSNodeName.setBounds(90, 24, 104, 16);
this.add(lblROSNodeName);
textfield = new JTextField();
textfield.setBounds(206, 19, 217, 26);
this.add(textfield);
textfield.setColumns(10);
createROSNodeButton = new JButton("Create ROS Node");
//createAgentButton.setBounds(177, 130, 117, 29);
createROSNodeButton.setBounds(290, 59, 133, 29);
this.add(createROSNodeButton);
createROSNodeButton.addActionListener(this);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == this.createROSNodeButton) {
String name = this.textfield.getText();
ROSNodeCodeGeneratorClient.ROSNodeFileGenerator(mypath, name);
this.dispose();
}
}
}

@ -0,0 +1,79 @@
package CodeGenerator;
import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import com.sun.xml.internal.fastinfoset.util.StringArray;
/**
* Created by Nickwong on 31/07/2018.
* 1-8
*/
public class ReadTxt {
/**
* TXT
*/
public static List<String> readFile(String pathname) {
//String pathname = "input.txt"; // 绝对路径或相对路径都可以,写入文件时演示相对路径,读取以上路径的input.txt文件
//防止文件建立或读取失败用catch捕捉错误并打印也可以throw;
//不关闭文件会导致资源的泄露,读写文件都同理
//Java7的try-with-resources可以优雅关闭文件异常时自动关闭文件详细解读https://stackoverflow.com/a/12665271
try (FileReader reader = new FileReader(pathname);
BufferedReader br = new BufferedReader(reader) // 建立一个对象,它把文件内容转成计算机能读懂的语言
) {
String line;
List<String> lineArray=new ArrayList<String>();
//网友推荐更加简洁的写法
while ((line = br.readLine()) != null) {
// 一次读入一行数据
//System.out.println(line);
lineArray.add(line);
}
return lineArray;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* TXT
*/
public static void writeFile(String pathname, String txt) {
try {
File writeName = new File(pathname); // 相对路径如果没有则要建立一个新的output.txt文件
writeName.createNewFile(); // 创建新文件,有同名的文件的话直接覆盖
try (FileWriter writer = new FileWriter(writeName);
BufferedWriter out = new BufferedWriter(writer)
) {
out.write(txt); // \r\n为换行
out.flush(); // 把缓存区内容压入文件
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* TXT
*/
public static void writeFileByAppending(String pathname, String txt) {
try {
File writeName = new File(pathname); // 相对路径如果没有则要建立一个新的output.txt文件
writeName.createNewFile(); // 创建新文件,有同名的文件的话直接覆盖
try (FileWriter writer = new FileWriter(writeName, true);
BufferedWriter out = new BufferedWriter(writer)
) {
out.write(txt); // \r\n为换行
out.flush(); // 把缓存区内容压入文件
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

@ -0,0 +1,45 @@
package SampleApplication.Agent;
import jade.core.AID;
import jade.core.behaviours.DataStore;
import jade.core.behaviours.ThreadedBehaviourFactory;
public class ${entity.className}<#if entity.superclass?has_content> extends ${entity.superclass} </#if>
{
<#list entity.properties as property>
private ${property.javaType} ${property.propertyName} = ;
</#list>
<#list tbfentity.tbfentities as tbfentity>
private ${tbfentity.superclass} ${tbfentity.className} = new ${tbfentity.superclass} ();
</#list>
<#list controllerentity.controllerentities as controllerentity>
private ${controllerentity.superclass} ${controllerentity.className} = new ${controllerentity.superclass}(this);
</#list>
/**
*jade.core.AID.AID(String name, boolean isGUID)
*/
<#list entity.entities as entity1>
private ${entity1.superclass} ${entity1.className} = new ${entity1.superclass} ();
</#list>
protect void setup() {
System.out.println("Agent " + getLocalName() + " waiting for operation...");
/**
*void rbehaviours.Controller.addTopic(String topicName, String topicType)
*/
<#list controllerentity.controllerentities as controllerentity>
${controllerentity.className}.addTopic();
</#list>
/**
*Behaviour jade.core.behaviours.ThreadedBehaviourFactory.wrap(Behaviour b)
*/
<#list tbfentity.tbfentities as tbfentity>
addBehaviour(${tbfentity.className}.wrap());
</#list>
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save