All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bidib.wizard.mvc.stepcontrol.model.StepControlModel Maven / Gradle / Ivy

There is a newer version: 2.0.29
Show newest version
package org.bidib.wizard.mvc.stepcontrol.model;

import java.beans.PropertyVetoException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.LongSupplier;

import org.apache.commons.collections4.CollectionUtils;
import org.bidib.wizard.model.ports.MotorPort;
import org.bidib.wizard.model.ports.SoundPort;
import org.bidib.wizard.model.stepcontrol.TurnTableType;
import org.bidib.wizard.mvc.stepcontrol.model.StepControlAspect.AspectPersistanceStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jgoodies.binding.beans.Model;
import com.jgoodies.common.collect.ArrayListModel;

public class StepControlModel extends Model {

    private static final long serialVersionUID = 1L;

    private static final Logger LOGGER = LoggerFactory.getLogger(StepControlModel.class);

    public enum OperationModeEnum {
        unknown, operational, emergencyStop, homingInProgress;
    }

    public static final String PROPERTYNAME_SELECTED_ASPECT = "selectedAspect";

    public static final String PROPERTYNAME_STEPCONTROL_ASPECTS = "stepControlAspects";

    public static final String PROPERTYNAME_CURRENT_POSITION = "currentPosition";

    public static final String PROPERTYNAME_TOTAL_STEPS = "totalSteps";

    public static final String PROPERTYNAME_MAX_CONFIGURED_ASPECTS = "maxConfiguredAspects";

    public static final String PROPERTYNAME_TURNTABLE_TYPE = "turnTableType";

    public static final String PROPERTYNAME_SPEED = "speed";

    public static final String PROPERTYNAME_ACCEL = "accel";

    public static final String PROPERTYNAME_DECEL = "decel";

    public static final String PROPERTYNAME_PUSH_INTERVAL = "pushInterval";

    public static final String PROPERTYNAME_OPERATIONAL_MODE = "operationalMode";

    public static final String PROPERTYNAME_CURRENT_DEGREES = "currentDegrees";

    public static final String PROPERTYNAME_TARGET_DEGREES = "targetDegrees";

    public static final String PROPERTYNAME_MOTOR_PORT = "motorPort";

    public static final String PROPERTYNAME_SOUND_PORTS = "soundPorts";

    public static final String PROPERTYNAME_SOUND_ACTIVE = "soundActive";

    private ArrayListModel stepControlAspects = new ArrayListModel<>();

    private StepControlAspect selectedAspect;

    private int maxConfiguredAspects;

    private TurnTableType turnTableType = TurnTableType.unknown;

    private Long currentPosition;

    private Long totalSteps;

    private int speed = 1;

    private int accel = 1;

    private int decel = 1;

    private Integer pushInterval;

    private OperationModeEnum operationalMode = OperationModeEnum.unknown;

    private double currentDegrees;

    private double targetDegrees;

    private MotorPort motorPort;

    private List soundPorts;

    private boolean soundActive;

    /**
     * @return the selectedAspect
     */
    public StepControlAspect getSelectedAspect() {
        return selectedAspect;
    }

    /**
     * @param selectedAspect
     *            the selectedAspect to set
     */
    public void setSelectedAspect(StepControlAspect selectedAspect) {
        StepControlAspect oldValue = this.selectedAspect;
        this.selectedAspect = selectedAspect;

        firePropertyChange(PROPERTYNAME_SELECTED_ASPECT, oldValue, selectedAspect);
    }

    /**
     * @return the stepControlAspects list model
     */
    public ArrayListModel getStepControlAspectsListModel() {
        return stepControlAspects;
    }

    /**
     * @return the stepControlAspects
     */
    public List getStepControlAspects() {
        return stepControlAspects;
    }

    /**
     * @param stepControlAspect
     *            the single stepControlAspect to add
     */
    public void addStepControlAspect(StepControlAspect stepControlAspect) {
        List oldValue = new ArrayList<>();
        oldValue.addAll(this.stepControlAspects);

        // // TODO fix this hack
        // if (stepControlAspect.getAspectNumber() == null) {
        // int size = stepControlAspects.size();
        // stepControlAspect.setAspectNumber(size + 1);
        // }

        this.stepControlAspects.add(stepControlAspect);

        firePropertyChange(PROPERTYNAME_STEPCONTROL_ASPECTS, oldValue, stepControlAspects);
    }

    /**
     * @param stepControlAspect
     *            the single stepControlAspect to remove
     */
    public void removeStepControlAspect(final StepControlAspect stepControlAspect) {
        List oldValue = new ArrayList<>();
        oldValue.addAll(this.stepControlAspects);

        int index = this.stepControlAspects.indexOf(stepControlAspect);

        this.stepControlAspects.remove(stepControlAspect);

        firePropertyChange(PROPERTYNAME_STEPCONTROL_ASPECTS, oldValue, stepControlAspects);

        if (index > -1) {
            this.stepControlAspects.fireContentsChanged(index);
        }
    }

    public void updateStepControlAspect(final StepControlAspect originalAspect, final StepControlAspect changedAspect) {
        LOGGER.info("Update originalAspect: {}", originalAspect);

        // make sure the aspect is in list
        int index = this.stepControlAspects.indexOf(originalAspect);

        if (index > -1) {
            // copy the new position and polarity
            originalAspect.setPosition(changedAspect.getPosition());

            if (TurnTableType.round == turnTableType) {
                // // calculate the opposite position
                // long oppositePosition = changedAspect.getPosition() + (totalSteps / 2);
                // if (oppositePosition > totalSteps) {
                // oppositePosition = changedAspect.getPosition() - (totalSteps / 2);
                // }
                originalAspect.setOppositePosition(changedAspect.getOppositePosition());
                originalAspect.setOppositePolarity(changedAspect.getOppositePolarity());
            }

            originalAspect.setPolarity(changedAspect.getPolarity());
            originalAspect.setStatus(AspectPersistanceStatus.statusTransient);

            this.stepControlAspects.fireContentsChanged(index);
        }
        else {
            LOGGER.warn("Original aspect is not in list of stepControlAspects: {}", originalAspect);
        }
    }

    /**
     * @param stepControlAspects
     *            the stepControlAspects to set
     */
    public void setStepControlAspects(List stepControlAspects) {
        List oldValue = new ArrayList<>();
        oldValue.addAll(this.stepControlAspects);

        this.stepControlAspects.clear();
        if (CollectionUtils.isNotEmpty(stepControlAspects)) {
            this.stepControlAspects.addAll(stepControlAspects);
        }

        firePropertyChange(PROPERTYNAME_STEPCONTROL_ASPECTS, oldValue, this.stepControlAspects);

        this.stepControlAspects.fireContentsChanged(0, this.stepControlAspects.getSize() - 1);
    }

    /**
     * @return the maxConfiguredAspects
     */
    public int getMaxConfiguredAspects() {
        return maxConfiguredAspects;
    }

    /**
     * @param maxConfiguredAspects
     *            the maxConfiguredAspects to set
     */
    public void setMaxConfiguredAspects(int maxConfiguredAspects) {
        int oldValue = this.maxConfiguredAspects;
        this.maxConfiguredAspects = maxConfiguredAspects;

        firePropertyChange(PROPERTYNAME_MAX_CONFIGURED_ASPECTS, oldValue, this.maxConfiguredAspects);
    }

    /**
     * @return the turnTableType
     */
    public TurnTableType getTurnTableType() {
        return turnTableType;
    }

    /**
     * @param turnTableType
     *            the turnTableType to set
     */
    public void setTurnTableType(TurnTableType turnTableType) {
        LOGGER.info("Set the turnTableType: {}", turnTableType);

        TurnTableType oldValue = this.turnTableType;
        this.turnTableType = turnTableType;

        firePropertyChange(PROPERTYNAME_TURNTABLE_TYPE, oldValue, turnTableType);
    }

    /**
     * @return the currentPosition
     */
    public Long getCurrentPosition() {
        return currentPosition;
    }

    /**
     * @param currentPosition
     *            the currentPosition to set
     */
    public void setCurrentPosition(Long currentPosition) {
        LOGGER.info("Set the current position: {}", currentPosition);

        Long oldValue = this.currentPosition;
        this.currentPosition = currentPosition;

        firePropertyChange(PROPERTYNAME_CURRENT_POSITION, oldValue, currentPosition);
    }

    /**
     * @return the totalSteps
     */
    public Long getTotalSteps() {
        return totalSteps;
    }

    /**
     * @param totalSteps
     *            the totalSteps to set
     */
    public void setTotalSteps(Long totalSteps) {
        LOGGER.info("Set the total steps: {}", totalSteps);

        Long oldValue = this.totalSteps;
        this.totalSteps = totalSteps;

        firePropertyChange(PROPERTYNAME_TOTAL_STEPS, oldValue, totalSteps);
    }

    /**
     * @return the speed
     */
    public int getSpeed() {
        return speed;
    }

    /**
     * @param speed
     *            the speed to set
     */
    public void setSpeed(int speed) {
        LOGGER.info("Set speed: {}", speed);

        int oldValue = this.speed;
        this.speed = speed;
        firePropertyChange(PROPERTYNAME_SPEED, oldValue, speed);
    }

    /**
     * @return the accel
     */
    public int getAccel() {
        return accel;
    }

    /**
     * @param accel
     *            the accel to set
     */
    public void setAccel(int accel) throws PropertyVetoException {

        // TODO validate the accel value
        validateConfigurationValue("accel", () -> accel);

        int oldValue = this.accel;
        this.accel = accel;
        firePropertyChange(PROPERTYNAME_ACCEL, oldValue, accel);
    }

    /**
     * @return the decel
     */
    public int getDecel() {
        return decel;
    }

    /**
     * @param decel
     *            the decel to set
     */
    public void setDecel(int decel) throws PropertyVetoException {

        // TODO validate the decel value
        validateConfigurationValue("decel", () -> decel);

        int oldValue = this.decel;
        this.decel = decel;
        firePropertyChange(PROPERTYNAME_DECEL, oldValue, decel);
    }

    /**
     * Check if the current configuration values for accel and decel are valid
     * 
     * @throws IllegalArgumentException
     *             thrown if invalid values detected
     */
    public void checkValidConfigurationValues() {

        validateConfigurationValue("decel", () -> this.decel);
        validateConfigurationValue("accel", () -> this.accel);
    }

    private void validateConfigurationValue(String valueIdentifier, final LongSupplier newValueSupplier) {
        Long totalSteps = getTotalSteps();
        if (totalSteps == null) {
            LOGGER.warn("The totalSteps are not available.");
            throw new IllegalArgumentException("The totalSteps are not available.");
        }
        long minDecel = totalSteps.longValue();
        minDecel = minDecel * newValueSupplier.getAsLong();
        if (minDecel < F_STEP_ACCEL_LIMIT) {
            LOGGER.warn("The configured '{}' value is too small: {}", valueIdentifier, newValueSupplier.getAsLong());
            throw new IllegalArgumentException(
                "The configured '" + valueIdentifier + "' value is too small: " + newValueSupplier.getAsLong());
        }
    }

    // = 1/((65536 / F_STEP_TIMER_676) ^2 / 720)
    private static final long F_STEP_ACCEL_LIMIT = 19150L;

    /**
     * @return the operationalMode
     */
    public OperationModeEnum getOperationalMode() {
        return operationalMode;
    }

    /**
     * @param operationalMode
     *            the operationalMode to set
     */
    public void setOperationalMode(OperationModeEnum operationalMode) {
        OperationModeEnum oldValue = this.operationalMode;
        this.operationalMode = operationalMode;

        LOGGER.info("setOperationalMode, old: {}, current: {}", oldValue, operationalMode);

        firePropertyChange(PROPERTYNAME_OPERATIONAL_MODE, oldValue, operationalMode);
    }

    /**
     * Clear all values from the model.
     */
    public void clearModel() {
        setStepControlAspects(null);
        setCurrentPosition(0L);
        setSelectedAspect(null);
        setTurnTableType(TurnTableType.unknown);
        setSpeed(1);

        try {
            setAccel(1);
        }
        catch (IllegalArgumentException | PropertyVetoException ex) {
            LOGGER.warn("Set accel failed", ex);
        }
        try {
            setDecel(1);
        }
        catch (IllegalArgumentException | PropertyVetoException ex) {
            LOGGER.warn("Set decel failed", ex);
        }
        // LOGGER.info("Clear the mode and set operational mode to unknown.");
        // setOperationalMode(OperationModeEnum.unknown);
    }

    public void setTurntableCurrentDegrees(double degrees) {
        double oldValue = currentDegrees;
        currentDegrees = degrees;

        firePropertyChange(PROPERTYNAME_CURRENT_DEGREES, oldValue, currentDegrees);
    }

    public double getTurntableCurrentDegrees() {
        return currentDegrees;
    }

    public void setTurntableTargetDegrees(double degrees) {
        double oldValue = targetDegrees;
        targetDegrees = degrees;

        firePropertyChange(PROPERTYNAME_TARGET_DEGREES, oldValue, targetDegrees);
    }

    public double getTurntableTargetDegrees() {
        return targetDegrees;
    }

    /**
     * @return the motorPort
     */
    public MotorPort getMotorPort() {
        return motorPort;
    }

    /**
     * @param motorPort
     *            the motorPort to set
     */
    public void setMotorPort(MotorPort motorPort) {
        MotorPort oldValue = this.motorPort;

        this.motorPort = motorPort;

        firePropertyChange(PROPERTYNAME_MOTOR_PORT, oldValue, motorPort);
    }

    /**
     * @return the soundPorts
     */
    public List getSoundPorts() {
        return soundPorts;
    }

    /**
     * @param soundPorts
     *            the soundPorts to set
     */
    public void setSoundPorts(List soundPorts) {
        List oldValue = this.soundPorts;

        this.soundPorts = soundPorts;

        firePropertyChange(PROPERTYNAME_SOUND_PORTS, oldValue, soundPorts);
    }

    /**
     * @param pushInterval
     *            the push interval to set
     */
    public void setPushInterval(Integer pushInterval) {
        Integer oldValue = this.pushInterval;

        this.pushInterval = pushInterval;
        firePropertyChange(PROPERTYNAME_PUSH_INTERVAL, oldValue, pushInterval);
    }

    /**
     * @return the push interval
     */
    public Integer getPushInterval() {
        return pushInterval;
    }

    /**
     * @return the soundActive
     */
    public boolean isSoundActive() {
        return soundActive;
    }

    /**
     * @param soundActive
     *            the soundActive to set
     */
    public void setSoundActive(boolean soundActive) {
        boolean oldValue = this.soundActive;
        this.soundActive = soundActive;

        firePropertyChange(PROPERTYNAME_SOUND_ACTIVE, oldValue, soundActive);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy