Skip to content
Snippets Groups Projects
Commit 34245470 authored by Florian Hölzl's avatar Florian Hölzl
Browse files

Cherry-picked SVN branch multideploy.

parent d7ce4c4f
No related branches found
No related tags found
No related merge requests found
Showing with 1305 additions and 0 deletions
build/
target/
org.fortiss.af3.platform.raspberry.ui/icons/console.png

469 B

/*--------------------------------------------------------------------------+
$Id: CameraInputHandler.java 23956 2018-04-11 14:15:25Z barner $
| |
| Copyright 2011 ForTISS GmbH |
| |
| 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. |
+--------------------------------------------------------------------------*/
package org.fortiss.af3.platform.raspberry.ui.handler;
import static org.fortiss.af3.platform.raspberry.ui.AF3PlatformRaspberryUIActivator.getImageDescriptor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.fortiss.af3.platform.raspberry.model.RaspberryPiReceiverBase;
import org.fortiss.af3.platform.raspberry.model.camera.CameraDistanceLeft;
import org.fortiss.tooling.kernel.ui.extension.base.NamedCommentedModelElementHandlerBase;
/**
* Handler for {@link CameraDistanceLeft}s and other camera model elements.
*
* @author hoelzl
* @author $Author: barner $
* @version $Rev: 23956 $
* @ConQAT.Rating GREEN Hash: D80CF94CBBADB4627AAEDA1F34ABF0A5
*/
public class CameraInputHandler extends
NamedCommentedModelElementHandlerBase<RaspberryPiReceiverBase> {
/** {@inheritDoc} */
@Override
public ImageDescriptor getIconImageDescriptor() {
return getImageDescriptor("icons/unknown.png");
}
}
/*--------------------------------------------------------------------------+
$Id: MotorControlInputHandler.java 23956 2018-04-11 14:15:25Z barner $
| |
| Copyright 2011 ForTISS GmbH |
| |
| 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. |
+--------------------------------------------------------------------------*/
package org.fortiss.af3.platform.raspberry.ui.handler;
import static org.fortiss.af3.platform.raspberry.ui.AF3PlatformRaspberryUIActivator.getImageDescriptor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.fortiss.af3.platform.raspberry.model.motorcontrol.MotorControlInput;
import org.fortiss.tooling.kernel.ui.extension.base.NamedCommentedModelElementHandlerBase;
/**
* Handler for {@link MotorControlInput}s.
*
* @author hoelzl
* @author $Author: barner $
* @version $Rev: 23956 $
* @ConQAT.Rating GREEN Hash: D80CF94CBBADB4627AAEDA1F34ABF0A5
*/
public class MotorControlInputHandler extends
NamedCommentedModelElementHandlerBase<MotorControlInput> {
/** {@inheritDoc} */
@Override
public ImageDescriptor getIconImageDescriptor() {
return getImageDescriptor("icons/unknown.png");
}
}
/*--------------------------------------------------------------------------+
$Id: MotorControlOutputHandler.java 23956 2018-04-11 14:15:25Z barner $
| |
| Copyright 2011 ForTISS GmbH |
| |
| 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. |
+--------------------------------------------------------------------------*/
package org.fortiss.af3.platform.raspberry.ui.handler;
import static org.fortiss.af3.platform.raspberry.ui.AF3PlatformRaspberryUIActivator.getImageDescriptor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.fortiss.af3.platform.raspberry.model.motorcontrol.MotorControlOutput;
import org.fortiss.tooling.kernel.ui.extension.base.NamedCommentedModelElementHandlerBase;
/**
* Handler for {@link MotorControlOutput}s.
*
* @author hoelzl
* @author $Author: barner $
* @version $Rev: 23956 $
* @ConQAT.Rating GREEN Hash: D80CF94CBBADB4627AAEDA1F34ABF0A5
*/
public class MotorControlOutputHandler extends
NamedCommentedModelElementHandlerBase<MotorControlOutput> {
/** {@inheritDoc} */
@Override
public ImageDescriptor getIconImageDescriptor() {
return getImageDescriptor("icons/unknown.png");
}
}
build/
target/
/*--------------------------------------------------------------------------+
$Id: MultiUnitMainGenerator.java 23075 2018-02-01 14:25:45Z ext.konstantin.tschernik $
| |
| Copyright 2017 fortiss GmbH |
| |
| 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. |
+--------------------------------------------------------------------------*/
package org.fortiss.af3.platform.raspberry.generator.executable;
import static org.fortiss.af3.component.utils.ComponentArchitectureUtils.findSourcePort;
import static org.fortiss.af3.component.utils.ComponentArchitectureUtils.isAtomicComponent;
import static org.fortiss.af3.deployment.utils.DeploymentUtils.findDeployedExecutionUnits;
import static org.fortiss.af3.platform.raspberry.generator.templates.RasPiCTemplates.getMultiUnitMainCFile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import org.conqat.lib.commons.collections.Pair;
import org.fortiss.af3.component.model.Channel;
import org.fortiss.af3.component.model.Component;
import org.fortiss.af3.component.model.InputPort;
import org.fortiss.af3.component.model.OutputPort;
import org.fortiss.af3.component.model.Port;
import org.fortiss.af3.deployment.model.Deployment;
import org.fortiss.af3.expression.model.definitions.Enumeration;
import org.fortiss.af3.expression.model.definitions.TypeDefinition;
import org.fortiss.af3.expression.model.types.TBool;
import org.fortiss.af3.expression.model.types.TDefinedType;
import org.fortiss.af3.expression.model.types.TDouble;
import org.fortiss.af3.expression.model.types.TInt;
import org.fortiss.af3.generator.common.model.source.AbstractUnit;
import org.fortiss.af3.platform.model.ExecutionUnit;
import org.fortiss.af3.platform.model.PlatformConnectorUnit;
import org.fortiss.af3.platform.model.Receiver;
import org.fortiss.af3.platform.model.Transmitter;
import org.fortiss.af3.platform.raspberry.model.ActuatorPWM;
import org.fortiss.af3.platform.raspberry.model.ConsoleOutput;
import org.fortiss.af3.platform.raspberry.model.RaspberryPi;
import org.fortiss.af3.platform.raspberry.model.brick.AccelerationXSensor;
import org.fortiss.af3.platform.raspberry.model.brick.AccelerationYSensor;
import org.fortiss.af3.platform.raspberry.model.brick.AccelerationZSensor;
import org.fortiss.af3.platform.raspberry.model.brick.ActuatorDigits;
import org.fortiss.af3.platform.raspberry.model.brick.AngularVelocityXSensor;
import org.fortiss.af3.platform.raspberry.model.brick.AngularVelocityYSensor;
import org.fortiss.af3.platform.raspberry.model.brick.AngularVelocityZSensor;
import org.fortiss.af3.platform.raspberry.model.brick.LaserRangeSensor;
import org.fortiss.af3.platform.raspberry.model.brick.UltraSonicSensor;
import org.fortiss.af3.platform.raspberry.model.camera.CameraDetectionStateLeft;
import org.fortiss.af3.platform.raspberry.model.camera.CameraDetectionStateRight;
import org.fortiss.af3.platform.raspberry.model.camera.CameraDistanceLeft;
import org.fortiss.af3.platform.raspberry.model.camera.CameraDistanceRight;
import org.fortiss.af3.platform.raspberry.model.camera.CameraYawAngle;
import org.fortiss.af3.platform.raspberry.model.gamepad.Button1;
import org.fortiss.af3.platform.raspberry.model.gamepad.Button2;
import org.fortiss.af3.platform.raspberry.model.gamepad.Button3;
import org.fortiss.af3.platform.raspberry.model.gamepad.Button4;
import org.fortiss.af3.platform.raspberry.model.gamepad.ButtonL2;
import org.fortiss.af3.platform.raspberry.model.gamepad.ButtonR2;
import org.fortiss.af3.platform.raspberry.model.gamepad.GamepadReceiverBase;
import org.fortiss.af3.platform.raspberry.model.motorcontrol.MotorControlInput;
import org.fortiss.af3.platform.raspberry.model.motorcontrol.MotorControlOutput;
import org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonA;
import org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonB;
import org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonHome;
import org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonSelect;
import org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonStart;
import org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonX;
import org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonY;
import org.fortiss.af3.platform.raspberry.model.rumblepad.DPadDown;
import org.fortiss.af3.platform.raspberry.model.rumblepad.DPadLeft;
import org.fortiss.af3.platform.raspberry.model.rumblepad.DPadRight;
import org.fortiss.af3.platform.raspberry.model.rumblepad.DPadUp;
import org.fortiss.af3.platform.raspberry.model.rumblepad.L2_Position;
import org.fortiss.af3.platform.raspberry.model.rumblepad.R2_Position;
import org.fortiss.af3.platform.raspberry.model.rumblepad.RumbleMagnitudeStrong;
import org.fortiss.af3.platform.raspberry.model.rumblepad.RumbleMagnitudeWeak;
import org.fortiss.af3.platform.raspberry.model.rumblepad.RumblepadReceiverBase;
import org.fortiss.af3.project.model.typesystem.IType;
import org.fortiss.tooling.kernel.extension.data.ITransformationContext;
import org.fortiss.tooling.kernel.model.INamedElement;
/**
* Separate class for generating the main.c file for use with CAN-based multi-unit deployments.
*
* @author hoelzl
* @author $Author: ext.konstantin.tschernik $
* @version $Rev: 23075 $
* @ConQAT.Rating RED Hash:
*/
class MultiUnitMainGenerator {
private static final int WAITING_SLEEP_IN_MICROS = 50;
private Deployment deployment;
private CanTransmissionCatalog catalog;
private RaspberryPi executionUnit;
private List<Component> atomicComponents;
private List<Pair<ExecutionUnit, Component>> deployedComponents;
private List<Pair<PlatformConnectorUnit, Port>> deployedPorts;
private HashMap<InputPort, Receiver> atomicInputToReceiver = new HashMap<>();
private HashMap<OutputPort, Transmitter> atomicOutputToTransmitter = new HashMap<>();
private ITransformationContext context;
private boolean useCamera;
private boolean useGamepad;
private boolean useRumblepad;
private boolean useDigits;
private boolean usePWM;
private boolean useUS;
private boolean useLaser;
private boolean useACC;
private boolean useConsole;
private boolean useRumble;
private OutputPort rumbleWeakPort = null;
private OutputPort rumbleStrongPort = null;
private boolean useVesc;
private int nrOfUsSensors = 0;
/** Constructor. */
public MultiUnitMainGenerator(Deployment deployment, CanTransmissionCatalog catalog,
RaspberryPi executionUnit, List<Component> atomicComponents,
List<Pair<ExecutionUnit, Component>> deployedComponents,
List<Pair<PlatformConnectorUnit, Port>> deployedPorts, ITransformationContext context) {
this.deployment = deployment;
this.catalog = catalog;
this.executionUnit = executionUnit;
this.deployedComponents = deployedComponents;
this.atomicComponents = atomicComponents;
this.deployedPorts = deployedPorts;
this.context = context;
for(Pair<PlatformConnectorUnit, Port> p : deployedPorts) {
PlatformConnectorUnit connector = p.getFirst();
analyzeDeployedPort(connector);
if(connector instanceof Receiver && p.getSecond() instanceof InputPort) {
InputPort deployedInput = (InputPort)p.getSecond();
for(Port atomicPort : findTargetPorts(deployedInput.getComponent(), deployedInput)) {
if(atomicPort instanceof InputPort) {
atomicInputToReceiver.put((InputPort)atomicPort, (Receiver)connector);
}
}
} else if(connector instanceof Transmitter && p.getSecond() instanceof OutputPort) {
OutputPort deployedOutput = (OutputPort)p.getSecond();
Port atomicPort = findSourcePort(deployedOutput.getComponent(), deployedOutput);
if(atomicPort instanceof OutputPort) {
atomicOutputToTransmitter.put((OutputPort)atomicPort, (Transmitter)connector);
}
}
}
}
/** Analyzes which {@link Receiver}s and {@link Transmitter}s are used. */
private void analyzeDeployedPort(PlatformConnectorUnit p) {
if(!useGamepad && p instanceof GamepadReceiverBase) {
useGamepad = true;
}
if(!useRumblepad &&
(p instanceof RumblepadReceiverBase || p instanceof RumbleMagnitudeWeak || p instanceof RumbleMagnitudeStrong)) {
useRumblepad = true;
}
if(!usePWM && p instanceof ActuatorPWM) {
usePWM = true;
}
if(!useUS && p instanceof UltraSonicSensor) {
useUS = true;
}
if(!useLaser && p instanceof LaserRangeSensor) {
useLaser = true;
}
if(!useDigits && p instanceof ActuatorDigits) {
useDigits = true;
}
if(!useACC &&
(p instanceof AccelerationXSensor || p instanceof AccelerationYSensor ||
p instanceof AccelerationZSensor || p instanceof AngularVelocityXSensor ||
p instanceof AngularVelocityYSensor || p instanceof AngularVelocityZSensor)) {
useACC = true;
}
if(!useConsole && p instanceof ConsoleOutput) {
useConsole = true;
}
if(!useVesc && (p instanceof MotorControlOutput || p instanceof MotorControlInput)) {
useVesc = true;
}
if(!useCamera &&
(p instanceof CameraYawAngle || p instanceof CameraDistanceLeft ||
p instanceof CameraDistanceRight || p instanceof CameraDetectionStateLeft) ||
p instanceof CameraDetectionStateRight) {
useCamera = true;
}
}
/** Creates the main.c file for deployments with a single execution units. */
public AbstractUnit createMultiUnitMain() {
String remoteUnitSetupCode = createRemoteUnitSetupCode();
String systemIncludes = createSystemIncludes();
String sensorVariables = createSensorVariables(deployedComponents, deployedPorts);
String systemInitCode = createInitCode(deployedComponents);
String remotePorts = createPortBuffers();
String componentSetup = createComponentStructureCode();
String componentImpl = createComponentImpl();
return getMultiUnitMainCFile(executionUnit.getName(), executionUnit.isCoordinatorUnit(),
executionUnit.getCanCoordinationID(), sensorVariables, systemInitCode,
remoteUnitSetupCode, systemIncludes, remotePorts, componentSetup, componentImpl,
executionUnit.getCycleTime(), WAITING_SLEEP_IN_MICROS);
}
/** Creates the C code for in-memory model of the AF3 component architecture. */
private String createComponentStructureCode() {
StringBuilder sb = new StringBuilder();
sb.append("// Instantiate components\n");
for(Component c : atomicComponents) {
createComponentInstantiationCode(sb, c);
}
instantiateOutputPorts(sb);
instantiateAndLinkInputPorts(sb);
return sb.toString();
}
/** Creates code for output ports. */
private void instantiateOutputPorts(StringBuilder sb) {
for(Component c : atomicComponents) {
String compId = identifierName(c);
sb.append("// Output ports of ").append(c.getName()).append("\n");
for(OutputPort outport : c.getOutputPorts()) {
if(atomicOutputToTransmitter.containsKey(outport)) {
// deployed to hardware
// FIXME: an atomic output might be needed remotely and on HW
continue;
}
String portVar = af3PortName(outport);
sb.append("\t").append(portVar).append(" = af3_port_create(");
sb.append(outport.getId()).append(", \"").append(outport.getName());
sb.append("\", ").append(getTypeName(outport)).append(", ");
boolean needsTransmission = catalog.isOutputNeededRemotely(outport);
sb.append(needsTransmission ? "true" : "false");
sb.append(");\n");
sb.append("\taf3_component_add_output(inst_").append(compId);
sb.append(", ").append(portVar).append(");\n");
sb.append("\tcopy_to_output_port_").append(getTypePostfix(outport)).append("(&")
.append(novalPortName(outport));
sb.append(", &").append(identifierName(outport));
sb.append(", ").append(portVar).append(");\n");
}
}
}
/** Returns the postfix for port copy functions of the given port. */
private Object getTypePostfix(Port port) {
IType type = port.getPortSpecification().getType();
if(type instanceof TInt) {
return "int";
}
if(type instanceof TDouble) {
return "double";
}
if(type instanceof TBool) {
return "boolean";
}
if(type instanceof TDefinedType) {
TypeDefinition tdef = ((TDefinedType)type).getDef();
if(tdef instanceof Enumeration) {
return "int";
}
}
return "unsupported_type";
}
/** Returns the type name of the given port. */
private Object getTypeName(Port port) {
IType type = port.getPortSpecification().getType();
if(type instanceof TInt) {
return "TYPE_INTEGER";
}
if(type instanceof TDouble) {
return "TYPE_DOUBLE";
}
if(type instanceof TBool) {
return "TYPE_BOOLEAN";
}
if(type instanceof TDefinedType) {
TypeDefinition tdef = ((TDefinedType)type).getDef();
if(tdef instanceof Enumeration) {
return "TYPE_INTEGER";
}
}
return "UNSUPPORTED_TYPE";
}
/** Creates remote input port proxies, input port buffers and links channels. */
private void instantiateAndLinkInputPorts(StringBuilder sb) {
// set for avoiding duplicate remote output port instantiation
HashSet<OutputPort> remoteOutputs = new HashSet<>();
for(Component c : atomicComponents) {
sb.append("// Local and remote input ports and channels of ").append(c.getName())
.append("\n");
for(InputPort inport : c.getInputPorts()) {
if(atomicInputToReceiver.containsKey(inport)) {
// HW allocation => no af3_port needed
continue;
}
String inPortName = af3PortName(inport);
sb.append("\t").append(inPortName).append(" = af3_port_create(");
sb.append(inport.getId()).append(", \"").append(inport.getName()).append("\", ");
sb.append(getTypeName(inport)).append(", false);\n");
sb.append("\taf3_component_add_input(inst_").append(identifierName(c));
sb.append(", ").append(inPortName).append(");\n");
OutputPort sourceOut = catalog.getSourcePort(inport);
// handle remote or local channel creation
if(catalog.hasRemoteSource(inport)) {
if(!remoteOutputs.contains(sourceOut)) {
createRemoteProxy(sb, sourceOut);
remoteOutputs.add(sourceOut);
}
}
if(sourceOut != null) {
createChannel(sb, sourceOut, inport);
}
}
}
}
/** Creates a channel between the given ports. */
private void createChannel(StringBuilder sb, OutputPort outport, InputPort inport) {
sb.append("\taf3_channel_create(").append(inport.getId());
sb.append(", \"ChannelTo").append(inport.getName()).append("\", ");
sb.append(af3PortName(outport)).append(", ");
sb.append(af3PortName(inport)).append(");\n");
}
/** Creates the remote input instantiation code. */
private void createRemoteProxy(StringBuilder sb, OutputPort remoteOut) {
// remote outputs instantiated only once
RaspberryPi owner = catalog.getRaspberryPi(remoteOut);
sb.append("\taf3_port_t* ").append(af3PortName(remoteOut));
sb.append(" = af3_component_remote_proxy_input_create(");
sb.append(catalog.getCanId(owner)).append(", ").append(remoteOut.getId());
sb.append(", \"").append(remoteOut.getName()).append("\", ");
sb.append(getTypeName(remoteOut)).append(");\n");
}
/** Creates code for instantiating components. */
private void createComponentInstantiationCode(StringBuilder sb, Component c) {
String compId = identifierName(c);
RaspberryPi owner = catalog.getRaspberryPi(c);
sb.append("// Instantiation of ").append(c.getName()).append("\n");
sb.append("\taf3_component_t* inst_").append(compId).append(" = af3_component_create(");
sb.append(catalog.getCanId(owner)).append(", \"").append(c.getName()).append("\", ");
sb.append(c.isStronglyCausal() ? "false" : "true");
sb.append(", impl_").append(compId).append(");\n");
sb.append("\taf3_component_system_add(inst_").append(compId).append(");\n");
sb.append("\tinit_").append(compId).append("();\n");
}
/** Creates static functions for each component. */
private String createComponentImpl() {
StringBuilder sb = new StringBuilder();
for(Component atomic : atomicComponents) {
createComponentImpl(atomic, sb);
}
return sb.toString();
}
/** Creates the component implementation code for the given component. */
private void createComponentImpl(Component atomic, StringBuilder sb) {
String compId = identifierName(atomic);
sb.append("// Implementation of ").append(atomic.getName()).append("\n");
sb.append("static void impl_").append(compId).append("(af3_component_t* comp) {\n");
if(useUS || useLaser || useACC) {
// Get Current time for the sensors
sb.append("uint64_t curr_time = time_util_get_current_micros();\n");
}
for(InputPort inport : atomic.getInputPorts()) {
if(atomicInputToReceiver.containsKey(inport)) {
// local hardware input ports
Receiver rec = atomicInputToReceiver.get(inport);
sb.append(createReadCode(rec, inport));
} else {
// local remote input ports
// FIXME: port type
sb.append("\tcopy_from_input_port_").append(getTypePostfix(inport));
sb.append("(").append(af3PortName(inport));
sb.append(", &").append(novalPortName(inport));
sb.append(", &").append(identifierName(inport)).append(");\n");
}
}
sb.append("\tperform_step_").append(compId).append("();\n");
useRumble = false;
for(OutputPort outport : atomic.getOutputPorts()) {
if(atomicOutputToTransmitter.containsKey(outport)) {
// local hardware output ports
Transmitter trn = atomicOutputToTransmitter.get(outport);
sb.append(createWriteCode(trn, outport));
} else {
// local or remote output port
// FIXME: port type
sb.append("\tcopy_to_output_port_int(&").append(novalPortName(outport));
sb.append(", &").append(identifierName(outport));
sb.append(", ").append(af3PortName(outport)).append(");\n");
}
}
if(useRumble) {
sb.append(createRumbleCode());
}
sb.append("}\n\n");
}
/** Setup code for remote units (used only in coordinator mode). */
private String createRemoteUnitSetupCode() {
if(!executionUnit.isCoordinatorUnit()) {
return "";
}
StringBuilder sb = new StringBuilder();
for(ExecutionUnit ecu : findDeployedExecutionUnits(deployment)) {
if(ecu != executionUnit && ecu instanceof RaspberryPi) {
RaspberryPi raspi = (RaspberryPi)ecu;
String idName = identifierName(raspi);
sb.append("protocol_can_remote_unit_config_t* ");
sb.append(idName).append(" = protocol_remote_unit_config_create(\"");
sb.append(idName).append("\", ");
sb.append(raspi.getCanCoordinationID()).append(");\n");
sb.append("list_util_append(remote_units, ");
sb.append(idName).append(");\n");
}
}
return sb.toString();
}
/** Creates declarations of remote unit buffers. */
private String createPortBuffers() {
StringBuilder sb = new StringBuilder();
for(Component atm : atomicComponents) {
for(InputPort inport : atm.getInputPorts()) {
if(!atomicInputToReceiver.containsKey(inport)) {
sb.append("static af3_port_t* " + af3PortName(inport) + " = NULL;\n");
}
}
for(OutputPort outport : atm.getOutputPorts()) {
if(!atomicOutputToTransmitter.containsKey(outport)) {
sb.append("static af3_port_t* " + af3PortName(outport) + " = NULL;\n");
}
}
}
return sb.toString();
}
/** Returns port name with 'af3_port_' prefix. */
private String af3PortName(Port port) {
return "af3_port_" + identifierName(port);
}
/** Returns port name with 'noval_' prefix. */
private String novalPortName(Port port) {
return "noval_" + identifierName(port);
}
/** Create #include for component architecture code. */
private String createSystemIncludes() {
StringBuilder sb = new StringBuilder();
for(Component atomic : atomicComponents) {
sb.append("#include \"" + identifierName(atomic) + ".h\"\n");
}
if(useCamera) {
sb.append("#include <camera_client.h>\n");
}
if(useGamepad) {
sb.append("#include <gamepad.h>\n");
}
if(useRumblepad) {
sb.append("#include <rumblepad.h>\n");
}
if(usePWM) {
sb.append("#include <temp_actuator.h>\n");
}
if(useUS || useLaser || useDigits || useACC) {
sb.append("#include <ip_connection.h>\n");
}
if(useUS) {
sb.append("#include <bricklet_distance_us.h>\n");
}
if(useLaser) {
sb.append("#include <bricklet_laser_range_finder.h>\n");
}
if(useACC) {
sb.append("#include <brick_imu_v2.h>\n");
}
if(useDigits) {
sb.append("#include <bricklet_segment_display_4x7.h>\n");
}
if(useVesc) {
sb.append("#include <commands.h>\n");
sb.append("#include <hal.h>\n");
}
sb.append("#include <stdio.h>\n");
return sb.toString();
}
/** Create the Sensor Variables and functions. */
private String createSensorVariables(List<Pair<ExecutionUnit, Component>> deployedComponents,
List<Pair<PlatformConnectorUnit, Port>> deployedPorts) {
StringBuilder sb = new StringBuilder();
sb.append("float Q = 0.022;\n");
sb.append("float R = 0.917;\n");
sb.append("float estimates[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};\n");
sb.append("float last_p[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};\n");
sb.append("float kalman_filter(float value, int sensor) {\n");
sb.append("\tif(sensor < 0 || sensor > 8) return -1;\n");
sb.append("\tfloat temp_est = estimates[sensor];\n");
sb.append("\tfloat p_temp = last_p[sensor] + Q;\n");
sb.append("\tfloat K = p_temp * (1.0*(p_temp + R));\n");
sb.append("\tfloat est = temp_est + K * (value - temp_est);\n");
sb.append("\tfloat P = (1-K)*p_temp;\n");
sb.append("\tlast_p[sensor] = P;\n");
sb.append("\testimates[sensor] = est;\n");
sb.append("\treturn est;\n");
sb.append("}\n\n");
if(usePWM) {
sb.append("int pwm_engine_fd = -1;\n");
sb.append("int pwm_steering_fd = -1;\n");
}
if(useDigits) {
sb.append("SegmentDisplay4x7 segment_display;\n");
sb.append("static void set_led_display (SegmentDisplay4x7 *segment_display, uint16_t value, bool showHex) {\n");
sb.append("static const uint8_t digits[] = {0x3f,0x06,0x5b,0x4f,\n");
sb.append(" 0x66,0x6d,0x7d,0x07,\n");
sb.append(" 0x7f,0x6f,0x77,0x7c,\n");
sb.append(" 0x39,0x5e,0x79,0x71};\n");
sb.append("if(showHex) {\n");
sb.append("uint8_t segments[4] = {digits[(value >> 12) & 0x0F], digits[(value >> 8) & 0x0F], digits[(value >> 4) & 0x0F], digits[value & 0x0F]};\n");
sb.append("segment_display_4x7_set_segments(segment_display, segments, 5, false);\n");
sb.append("} else {\n");
sb.append("uint8_t segments[4] = {digits[(value%10000)/1000], digits[(value%1000)/100], digits[(value%100)/10], digits[value%10]};\n");
sb.append("segment_display_4x7_set_segments(segment_display, segments, 5, false);\n");
sb.append("}\n");
sb.append("}\n\n");
}
if(useUS) {
sb.append("uint16_t ultra_sonic_A;\n");
sb.append("uint64_t us_A_last_cb_time = 0;\n");
sb.append("char* uid_us_A = \"zpW\";\n");
sb.append("void us_A_callback(uint16_t distance, void *data) {\n");
sb.append("ultra_sonic_A = kalman_filter(distance, 0);\n");
sb.append("us_A_last_cb_time = time_util_get_current_micros();\n");
sb.append("}\n");
sb.append("uint16_t ultra_sonic_B;\n");
sb.append("uint64_t us_B_last_cb_time = 0;\n");
sb.append("char* uid_us_B = \"zqN\";\n");
sb.append("void us_B_callback(uint16_t distance, void *data) {\n");
sb.append("us_B_last_cb_time = time_util_get_current_micros();\n");
sb.append("ultra_sonic_B = kalman_filter(distance, 1);\n");
sb.append("}\n\n");
}
if(useLaser) {
sb.append("int16_t laser_distance;\n");
sb.append("uint64_t laser_last_cb_time = 0;\n");
sb.append("void laser_callback(uint16_t distance, void *data) {\n");
sb.append("laser_distance = kalman_filter(distance, 2);\n");
sb.append("laser_last_cb_time = time_util_get_current_micros();\n");
sb.append("}\n\n");
}
if(useACC) {
sb.append("float acceleration_X, acceleration_Y, acceleration_Z;\n");
sb.append("uint64_t acc_last_cb_time = 0;\n");
sb.append("void acc_callback(int16_t x, int16_t y, int16_t z, void* data) {\n");
sb.append("if (abs(x - acceleration_X) > 2 * 10 * 100 ||\n");
sb.append("abs(y - acceleration_Y) > 2 * 10 * 100 ||\n");
sb.append("abs(z - acceleration_Z) > 2 * 10 * 100)\n");
sb.append(" return;\n");
sb.append("acceleration_X = kalman_filter(x, 3) / 100.0;\n");
sb.append("acceleration_Y = kalman_filter(y, 4) / 100.0;\n");
sb.append("acceleration_Z = kalman_filter(z, 5) / 100.0;\n");
sb.append("acc_last_cb_time = time_util_get_current_micros();\n");
sb.append("}\n\n");
sb.append("float angularVelocity_X, angularVelocity_Y, angularVelocity_Z;\n");
sb.append("uint64_t angV_last_cb_time = 0;\n");
sb.append("void angV_callback(int16_t x, int16_t y, int16_t z, void* data) {\n");
sb.append("angularVelocity_X = kalman_filter(x, 6) / 16;\n");
sb.append("angularVelocity_Y = kalman_filter(y, 7) / 16;\n");
sb.append("angularVelocity_Z = kalman_filter(z, 8) / 16;\n");
sb.append("angV_last_cb_time = time_util_get_current_micros();\n");
sb.append("}\n\n");
}
return sb.toString();
}
/** Returns the port and ID identifier. */
private String identifierName(INamedElement element) {
String name = element.getName() != null ? element.getName().replace(' ', '_') : "";
return name.replace(' ', '_') + "_ID_" + element.getId();
}
/** Creates the read code for the given receiver and port. */
private String createWriteCode(Transmitter transmitter, OutputPort outport) {
if(transmitter instanceof ActuatorPWM) {
ActuatorPWM act = (ActuatorPWM)transmitter;
String result = "if(!noval_" + identifierName(outport) + ") {\n";
if(act.getChannelID() == 0) {
result +=
"temp_actuator_device_set_target(pwm_engine_fd, 0, (uint16_t)" +
identifierName(outport) + ");\n";
} else {
result +=
"temp_actuator_device_set_target(pwm_steering_fd, 0, (uint16_t)" +
identifierName(outport) + ");\n";
}
result += "}\n";
return result;
}
if(transmitter instanceof ActuatorDigits) {
ActuatorDigits digits = (ActuatorDigits)transmitter;
String result = "if(!noval_" + identifierName(outport) + ") {\n";
result +=
"set_led_display(&segment_display, (uint16_t)" + identifierName(outport) +
", " + digits.isShowHexValue() + ");\n";
result += "}\n";
return result;
}
if(transmitter instanceof ConsoleOutput) {
String result = "\tif(!noval_" + identifierName(outport) + ") {\n";
result +=
"\t\tprintf(\"" + outport.getName() + " = %i\\n\", " + identifierName(outport) +
");\n";
result += "\t} else {\n";
result += "\t\tprintf(\"" + outport.getName() + " = NoVal\\n\");\n";
result += "\t}\n";
return result;
}
if(transmitter instanceof RumbleMagnitudeWeak) {
useRumble = true;
rumbleWeakPort = outport;
}
if(transmitter instanceof RumbleMagnitudeStrong) {
useRumble = true;
rumbleStrongPort = outport;
}
if(transmitter instanceof MotorControlOutput) {
String result = "if(!noval_" + identifierName(outport) + ") {\n";
result += "setVelocity(" + identifierName(outport) + ");\n";
result += "}\n";
return result;
}
return "";
}
/** Creates Code for Rumble */
private String createRumbleCode() {
StringBuilder sb = new StringBuilder();
sb.append("rumblepad_set_rumble(");
if(rumbleStrongPort != null) {
sb.append("!noval_" + identifierName(rumbleStrongPort) + " ? " +
identifierName(rumbleStrongPort) + " : 0, ");
} else {
sb.append("0, ");
}
if(rumbleWeakPort != null) {
sb.append("!noval_" + identifierName(rumbleWeakPort) + " ? " +
identifierName(rumbleWeakPort) + " : 0, ");
} else {
sb.append("0, ");
}
sb.append("cycle_time * 0.9, 0);\n");
return sb.toString();
}
/** Creates the read code for the given receiver and port. */
private String createReadCode(Receiver receiver, InputPort inport) {
if(receiver instanceof CameraDistanceLeft) {
StringBuilder sb = new StringBuilder();
sb.append("noval_" + identifierName(inport) + " = false;\n");
sb.append(identifierName(inport)).append(" = camera_client_get_distance_left();\n");
return sb.toString();
}
if(receiver instanceof CameraDistanceRight) {
StringBuilder sb = new StringBuilder();
sb.append("noval_" + identifierName(inport) + " = false;\n");
sb.append(identifierName(inport)).append(" = camera_client_get_distance_right();\n");
return sb.toString();
}
if(receiver instanceof CameraDetectionStateLeft) {
StringBuilder sb = new StringBuilder();
sb.append("noval_" + identifierName(inport) + " = false;\n");
sb.append(identifierName(inport)).append(
" = camera_client_get_detection_state_left();\n");
return sb.toString();
}
if(receiver instanceof CameraDetectionStateRight) {
StringBuilder sb = new StringBuilder();
sb.append("noval_" + identifierName(inport) + " = false;\n");
sb.append(identifierName(inport)).append(
" = camera_client_get_detection_state_right();\n");
return sb.toString();
}
if(receiver instanceof CameraYawAngle) {
StringBuilder sb = new StringBuilder();
sb.append("noval_" + identifierName(inport) + " = false;\n");
sb.append(identifierName(inport)).append(" = camera_client_get_yaw_angle();\n");
return sb.toString();
}
if(receiver instanceof UltraSonicSensor) {
StringBuilder sb = new StringBuilder();
UltraSonicSensor sensor = (UltraSonicSensor)receiver;
if(nrOfUsSensors == 0) {
sb.append("noval_" + identifierName(inport) + " = true;\n");
sb.append("if (!strcmp(\"" + sensor.getUniqueBrickletID() + "\", uid_us_A)) {\n");
sb.append("float diff_A = (curr_time - us_A_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
sb.append("if (diff_A < 1.0) {\n");
sb.append("noval_" + identifierName(inport) + " = false;\n");
sb.append(identifierName(inport) + " = ultra_sonic_A;\n}\n");
sb.append("}\n");
} else if(nrOfUsSensors == 1) {
sb.append("noval_" + identifierName(inport) + " = true;\n");
sb.append("if (!strcmp(\"" + sensor.getUniqueBrickletID() + "\", uid_us_B)){\n");
sb.append("float diff_B = (curr_time - us_B_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
sb.append("if (diff_B < 1.0) {\n");
sb.append("noval_" + identifierName(inport) + " = false;\n");
sb.append(identifierName(inport) + " = ultra_sonic_B;\n}\n");
sb.append("}\n");
}
nrOfUsSensors++;
return sb.toString();
}
if(receiver instanceof LaserRangeSensor) {
StringBuilder sb = new StringBuilder();
sb.append("float diff_laser = (curr_time - laser_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
sb.append("if (diff_laser < 1.0) {\n");
sb.append("noval_" + identifierName(inport) + " = false;\n");
sb.append(identifierName(inport) + " = laser_distance;\n");
sb.append("} else {\n");
sb.append("noval_" + identifierName(inport) + " = true;\n");
sb.append("}\n");
return sb.toString();
}
if(receiver instanceof AccelerationXSensor) {
StringBuilder sb = new StringBuilder();
sb.append("float diff_accX = (curr_time - acc_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
sb.append("if (diff_accX < 1.0) {\n");
sb.append("noval_" + identifierName(inport) + " = false;\n");
sb.append(identifierName(inport) + " = acceleration_X;\n");
sb.append("} else {\n");
sb.append("noval_" + identifierName(inport) + " = true;\n");
sb.append("}\n");
return sb.toString();
}
if(receiver instanceof AccelerationYSensor) {
StringBuilder sb = new StringBuilder();
sb.append("float diff_accY = (curr_time - acc_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
sb.append("if (diff_accY < 1.0) {\n");
sb.append("noval_" + identifierName(inport) + " = false;\n");
sb.append(identifierName(inport) + " = acceleration_Y;\n");
sb.append("} else {\n");
sb.append("noval_" + identifierName(inport) + " = true;\n");
sb.append("}\n");
return sb.toString();
}
if(receiver instanceof AccelerationZSensor) {
StringBuilder sb = new StringBuilder();
sb.append("float diff_accZ = (curr_time - acc_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
sb.append("if (diff_accZ < 1.0) {\n");
sb.append("noval_" + identifierName(inport) + " = false;\n");
sb.append(identifierName(inport) + " = acceleration_Z;\n");
sb.append("} else {\n");
sb.append("noval_" + identifierName(inport) + " = true;\n");
sb.append("}\n");
return sb.toString();
}
if(receiver instanceof AngularVelocityXSensor) {
StringBuilder sb = new StringBuilder();
sb.append("float diff_angV_X = (curr_time - angV_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
sb.append("if (diff_angV_X < 1.0) {\n");
sb.append("noval_" + identifierName(inport) + " = false;\n");
sb.append(identifierName(inport) + " = angularVelocity_X;\n");
sb.append("} else {\n");
sb.append("noval_" + identifierName(inport) + " = true;\n");
sb.append("}\n");
return sb.toString();
}
if(receiver instanceof AngularVelocityYSensor) {
StringBuilder sb = new StringBuilder();
sb.append("float diff_angV_Y = (curr_time - angV_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
sb.append("if (diff_angV_Y < 1.0) {\n");
sb.append("noval_" + identifierName(inport) + " = false;\n");
sb.append(identifierName(inport) + " = angularVelocity_Y;\n");
sb.append("} else {\n");
sb.append("noval_" + identifierName(inport) + " = true;\n");
sb.append("}\n");
return sb.toString();
}
if(receiver instanceof AngularVelocityZSensor) {
StringBuilder sb = new StringBuilder();
sb.append("float diff_angV_Z = (curr_time - angV_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
sb.append("if (diff_angV_Z < 1.0) {\n");
sb.append("noval_" + identifierName(inport) + " = false;\n");
sb.append(identifierName(inport) + " = angularVelocity_Z;\n");
sb.append("} else {\n");
sb.append("noval_" + identifierName(inport) + " = true;\n");
sb.append("}\n");
return sb.toString();
}
if(receiver instanceof MotorControlInput) {
StringBuilder sb = new StringBuilder();
sb.append("noval_" + identifierName(inport) + " = false;\n");
sb.append(identifierName(inport) + " = getVelocity();\n");
return sb.toString();
}
if(receiver instanceof Button1) {
return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_1", inport);
}
if(receiver instanceof Button2) {
return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_2", inport);
}
if(receiver instanceof Button3) {
return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_3", inport);
}
if(receiver instanceof Button4) {
return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_4", inport);
}
if(receiver instanceof org.fortiss.af3.platform.raspberry.model.gamepad.ButtonL1) {
return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_L1", inport);
}
if(receiver instanceof ButtonL2) {
return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_L2", inport);
}
if(receiver instanceof org.fortiss.af3.platform.raspberry.model.gamepad.ButtonR1) {
return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_R1", inport);
}
if(receiver instanceof ButtonR2) {
return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_R2", inport);
}
if(receiver instanceof org.fortiss.af3.platform.raspberry.model.gamepad.Right_StickX_Position) {
return gamepadReadCode("gamepad_get_axis_position",
"GAMEPAD_AXIS_RIGHT_STICK_HORIZONTAL", inport);
}
if(receiver instanceof org.fortiss.af3.platform.raspberry.model.gamepad.Right_StickY_Position) {
return gamepadReadCode("gamepad_get_axis_position",
"GAMEPAD_AXIS_RIGHT_STICK_VERTICAL", inport);
}
if(receiver instanceof org.fortiss.af3.platform.raspberry.model.gamepad.Left_StickX_Position) {
return gamepadReadCode("gamepad_get_axis_position",
"GAMEPAD_AXIS_LEFT_STICK_HORIZONTAL", inport);
}
if(receiver instanceof org.fortiss.af3.platform.raspberry.model.gamepad.Left_StickY_Position) {
return gamepadReadCode("gamepad_get_axis_position", "GAMEPAD_AXIS_LEFT_STICK_VERTICAL",
inport);
}
if(receiver instanceof ButtonA) {
return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_A", inport);
}
if(receiver instanceof ButtonB) {
return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_B", inport);
}
if(receiver instanceof ButtonX) {
return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_X", inport);
}
if(receiver instanceof ButtonY) {
return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_Y", inport);
}
if(receiver instanceof ButtonStart) {
return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_START", inport);
}
if(receiver instanceof ButtonSelect) {
return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_SELECT", inport);
}
if(receiver instanceof ButtonHome) {
return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_MODE", inport);
}
if(receiver instanceof DPadDown) {
return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_DPAD_DOWN", inport);
}
if(receiver instanceof DPadUp) {
return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_DPAD_UP", inport);
}
if(receiver instanceof DPadLeft) {
return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_DPAD_LEFT", inport);
}
if(receiver instanceof DPadRight) {
return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_DPAD_RIGHT", inport);
}
if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonL1) {
return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_L1", inport);
}
if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonR1) {
return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_R1", inport);
}
if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonL3) {
return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_L3", inport);
}
if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonR3) {
return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_R3", inport);
}
if(receiver instanceof L2_Position) {
return gamepadReadCode("rumblepad_get_axis_position", "RUMBLEPAD_AXIS_L2", inport);
}
if(receiver instanceof R2_Position) {
return gamepadReadCode("rumblepad_get_axis_position", "RUMBLEPAD_AXIS_R2", inport);
}
if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.Left_StickX_Position) {
return gamepadReadCode("rumblepad_get_axis_position",
"RUMBLEPAD_AXIS_LEFT_STICK_HORIZONTAL", inport);
}
if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.Left_StickY_Position) {
return gamepadReadCode("rumblepad_get_axis_position",
"RUMBLEPAD_AXIS_LEFT_STICK_VERTICAL", inport);
}
if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.Right_StickX_Position) {
return gamepadReadCode("rumblepad_get_axis_position",
"RUMBLEPAD_AXIS_RIGHT_STICK_HORIZONTAL", inport);
}
if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.Right_StickY_Position) {
return gamepadReadCode("rumblepad_get_axis_position",
"RUMBLEPAD_AXIS_RIGHT_STICK_VERTICAL", inport);
}
return "";
}
/** Creates read code for gamepad state. */
private String gamepadReadCode(String gamepadFun, String btnId, InputPort inport) {
String noval = "\tnoval_" + identifierName(inport) + " = false;\n";
String setBtn = "\t" + identifierName(inport) + " = " + gamepadFun + "(" + btnId + ");\n";
return noval + setBtn;
}
/** Create the initialize code. */
private String createInitCode(List<Pair<ExecutionUnit, Component>> deployedComponents) {
int createdUsSensors = 0;
StringBuilder sb = new StringBuilder();
if(useCamera) {
String addr = executionUnit.getCameraServerAddress();
String port = executionUnit.getCameraServerPort();
sb.append("camera_client_initialize(\"" + addr + "\", \"" + port + "\");\n");
}
if(useUS || useLaser || useDigits || useACC) {
sb.append("IPConnection brick_connection;\n");
sb.append("ipcon_create(&brick_connection);\n");
sb.append("if(ipcon_connect(&brick_connection, BRICK_HOST, BRICK_PORT) < 0) {\n");
sb.append("perror(\"Failed to connect to brick sub-system.\");\n");
sb.append("return 1;\n");
sb.append("}\n\n");
}
if(useUS) {
for(Pair<PlatformConnectorUnit, Port> p : deployedPorts) {
Receiver rec = atomicInputToReceiver.get(p.getSecond());
if(createdUsSensors >= 2)
break;
if(rec instanceof UltraSonicSensor) {
UltraSonicSensor sensor = (UltraSonicSensor)p.getFirst();
if(createdUsSensors == 0) {
sb.append("DistanceUS DistanceUS_A;\n");
sb.append("uid_us_A = \"" + sensor.getUniqueBrickletID() + "\";\n");
sb.append("distance_us_create(&DistanceUS_A, \"" +
sensor.getUniqueBrickletID() + "\", &brick_connection);\n");
sb.append("distance_us_register_callback(&DistanceUS_A, DISTANCE_US_CALLBACK_DISTANCE, (void*)us_A_callback, NULL);\n");
sb.append("distance_us_set_distance_callback_period(&DistanceUS_A, 10);\n");
} else {
sb.append("DistanceUS DistanceUS_B;\n");
sb.append("uid_us_B = \"" + sensor.getUniqueBrickletID() + "\";\n");
sb.append("distance_us_create(&DistanceUS_B, \"" +
sensor.getUniqueBrickletID() + "\", &brick_connection);\n");
sb.append("distance_us_register_callback(&DistanceUS_B, DISTANCE_US_CALLBACK_DISTANCE, (void*)us_B_callback, NULL);\n");
sb.append("distance_us_set_distance_callback_period(&DistanceUS_B, 10);\n");
}
createdUsSensors++;
}
}
}
if(useLaser) {
sb.append("LaserRangeFinder laser;\n");
sb.append("laser_range_finder_create(&laser, \"CQ9\", &brick_connection);\n");
sb.append("laser_range_finder_enable_laser(&laser);\n");
sb.append("laser_range_finder_register_callback(&laser, LASER_RANGE_FINDER_CALLBACK_DISTANCE, (void*)laser_callback, NULL);\n");
sb.append("laser_range_finder_set_distance_callback_period(&laser, 10);\n");
}
if(useDigits) {
sb.append("segment_display_4x7_create(&segment_display, \"wNK\", &brick_connection);\n");
}
if(useACC) {
sb.append("IMUV2 imu;\n");
sb.append("imu_v2_create(&imu, \"6xCD6s\", &brick_connection);\n");
sb.append("imu_v2_register_callback(&imu, IMU_V2_CALLBACK_LINEAR_ACCELERATION, (void*)acc_callback, NULL);\n");
sb.append("imu_v2_set_linear_acceleration_period(&imu, 5);\n");
sb.append("imu_v2_register_callback(&imu, IMU_V2_CALLBACK_ANGULAR_VELOCITY, (void*)angV_callback, NULL);\n");
sb.append("imu_v2_set_angular_velocity_period(&imu, 5);\n");
}
if(usePWM) {
sb.append("pwm_steering_fd = temp_actuator_initialize(\"/dev/ttyACM0\");\n");
sb.append("pwm_engine_fd = temp_actuator_initialize(\"/dev/ttyACM2\");\n\n");
}
if(useGamepad) {
sb.append("gamepad_configuration_t* gamepad_config = malloc(sizeof(gamepad_configuration_t));\n");
sb.append("gamepad_config->device_id = \"/dev/input/js0\";\n");
sb.append("gamepad_config->waiting_sleep_in_micros = " + WAITING_SLEEP_IN_MICROS +
";\n");
sb.append("gamepad_config->axis_callback = NULL;\n");
sb.append("gamepad_config->button_callback = NULL;\n");
sb.append("gamepad_initialize(gamepad_config);\n\n");
}
if(useRumblepad) {
sb.append("while(access(\"/dev/input/js0\", F_OK) == -1) {\n");
sb.append("sleep(1);\n");
sb.append("printf(\"Could not access gamepad device. Trying again in 1s.\\n\");\n");
sb.append("}\n");
sb.append("rumblepad_configuration_t* rumblepad_config = malloc(sizeof(rumblepad_configuration_t));\n");
sb.append("rumblepad_config->device_id = \"/dev/input/js0\";\n");
sb.append("rumblepad_config->waiting_sleep_in_micros = " + WAITING_SLEEP_IN_MICROS +
";\n");
sb.append("rumblepad_config->axis_callback = NULL;\n");
sb.append("rumblepad_config->button_callback = NULL;\n");
sb.append("rumblepad_initialize(rumblepad_config);\n\n");
}
if(useVesc) {
sb.append("initUSB(\"/dev/vesc\", B115200);\n");
}
return sb.toString();
}
/** Creates the function call code. */
private String makeCall(String function, Component c) {
StringBuilder sb = new StringBuilder();
sb.append(function).append('_').append(c.getName());
sb.append("_ID_").append(c.getId()).append("();\n");
return sb.toString();
}
/** Find sub-structure of component port targets. */
public static List<Port> findTargetPorts(Component boundary, Port port) {
List<Port> targets = new ArrayList<Port>();
if(isAtomicComponent(port.getComponent())) {
targets.add(port);
return targets;
}
LinkedList<Port> explore = new LinkedList<Port>();
for(Channel ch : port.getOutgoingChannels()) {
explore.add(ch.getTarget());
}
while(!explore.isEmpty()) {
Port testee = explore.removeFirst();
if(testee.getComponent() == boundary || isAtomicComponent(testee.getComponent()) ||
testee.getOutgoing().isEmpty()) {
targets.add(testee);
} else {
for(Channel ch : testee.getOutgoingChannels()) {
explore.add(ch.getTarget());
}
}
}
return targets;
}
}
group MainFile;
MainFile(UNIT_NAME,
COORDINATOR_OR_WORKER,
CAN_ID_LOCAL_UNIT,
SYSTEM_INIT_CODE,
SENSOR_VARIABLES,
REMOTE_UNIT_SETUP_CODE,
SYSTEM_INCLUDES,
COMPONENT_PORTS,
COMPONENT_SETUP,
COMPONENT_IMPL,
CYCLE_TIME_IN_MILLIS,
THREAD_SLEEPTIME_IN_MICROS) ::= <<
// due to current data dictionary declaration of GENTYPE_boolean
// system include must be first
/******************** BEGIN_@GENERATED ***********************/
$SYSTEM_INCLUDES$
/********************* END_@GENERATED ************************/
#include <stdbool.h>
#include <stddef.h>
#include <unistd.h>
#include <af3.h>
#include <af3_component.h>
#include <af3_component_remote_proxy.h>
#include <debugprint.h>
#include <listutil.h>
#include <protocol_control_center.h>
#include <protocol_coordinator.h>
#include <protocol_factory.h>
#include <timeutil.h>
#include "data.h"
int global_debug_print_level = DEBUG_PRINT_LEVEL_NONE;
const int cycle_time = $CYCLE_TIME_IN_MILLIS$;
#define BRICK_HOST "localhost"
#define BRICK_PORT 4223
/******************** BEGIN_@GENERATED ***********************/
$COMPONENT_PORTS$
$SENSOR_VARIABLES$
/********************* END_@GENERATED ************************/
/******************** BEGIN_@GENERATED ***********************/
$COMPONENT_IMPL$
/********************* END_@GENERATED ************************/
static void initialize_af3_subsystem() {
af3_module_initialize("$UNIT_NAME$", 0, NULL, NULL);
af3_component_module_initialize($THREAD_SLEEPTIME_IN_MICROS$, default_send_remote_impl);
af3_component_remote_proxy_module_initialize();
can_thread_add_reception_listener(default_recv_remote_impl);
/******************** BEGIN_@GENERATED ***********************/
$COMPONENT_SETUP$
/********************* END_@GENERATED ************************/
}
static void worker() {
af3_component_run_system();
af3_component_remote_proxy_clear_inputs();
}
int main(int argc, char** argv) {
if(argc >= 2) {
int dbg = atoi(argv[1]);
if(dbg < 0) {
dbg = 0;
} else if (dbg > 3) {
dbg = 3;
}
global_debug_print_level = dbg;
}
if (!can_thread_create("can0")) {
return -1;
}
can_thread_set_thread_sleep_in_micros($THREAD_SLEEPTIME_IN_MICROS$);
/******************** BEGIN_@GENERATED ***********************/
$SYSTEM_INIT_CODE$
/********************* END_@GENERATED ************************/
initialize_af3_subsystem();
protocol_can_config_t* can_config = protocol_can_config_create(0x01, 0x00, $CAN_ID_LOCAL_UNIT$);
protocol_worker_clock_config_t* clock_config =
protocol_worker_clock_config_create(cycle_time, 0, $THREAD_SLEEPTIME_IN_MICROS$);
protocol_worker_computation_config_t* computation_config =
protocol_worker_computation_config_create("$UNIT_NAME$", worker, 0);
#if $COORDINATOR_OR_WORKER$ == 1
// create list of remote units
list_t* remote_units = list_util_create_list();
/******************** BEGIN_@GENERATED ***********************/
$REMOTE_UNIT_SETUP_CODE$
/********************* END_@GENERATED ************************/
// run the unit coordinator protocol mode
int result = protocol_coordinator_main(can_config, clock_config, computation_config, remote_units);
#else
// run the unit in worker protocol mode
int result = protocol_worker_main(can_config, clock_config, computation_config);
#endif
can_thread_terminate();
free(can_config);
free(clock_config);
free(computation_config);
return result;
}
>>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment